authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-12-09 13:59:59-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-12-12 01:58:21-05:00
logc13857e504f5893cabf182dde1e826131f2acf24
tree23d77542db837bb1f7f4277e9e8b83948852fbac
parent27e5047a888fbfd6c9db6a8374e070eb0deb5d0a

windows: type safety improvements and more ntdll functions


16 files changed, 3131 insertions(+), 1343 deletions(-)

lib/std/Build/Watch.zig+21-12
...@@ -366,7 +366,7 @@ const Os = switch (builtin.os.tag) {...@@ -366,7 +366,7 @@ const Os = switch (builtin.os.tag) {
366 var attr = windows.OBJECT_ATTRIBUTES{366 var attr = windows.OBJECT_ATTRIBUTES{
367 .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),367 .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
368 .RootDirectory = if (std.fs.path.isAbsoluteWindowsW(sub_path_w.span())) null else root_fd,368 .RootDirectory = if (std.fs.path.isAbsoluteWindowsW(sub_path_w.span())) null else root_fd,
369 .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.369 .Attributes = .{},
370 .ObjectName = &nt_name,370 .ObjectName = &nt_name,
371 .SecurityDescriptor = null,371 .SecurityDescriptor = null,
372 .SecurityQualityOfService = null,372 .SecurityQualityOfService = null,
...@@ -375,14 +375,23 @@ const Os = switch (builtin.os.tag) {...@@ -375,14 +375,23 @@ const Os = switch (builtin.os.tag) {
375375
376 switch (windows.ntdll.NtCreateFile(376 switch (windows.ntdll.NtCreateFile(
377 &dir_handle,377 &dir_handle,
378 windows.SYNCHRONIZE | windows.GENERIC_READ | windows.FILE_LIST_DIRECTORY,378 .{
379 .SPECIFIC = .{ .FILE_DIRECTORY = .{
380 .LIST = true,
381 } },
382 .STANDARD = .{ .SYNCHRONIZE = true },
383 .GENERIC = .{ .READ = true },
384 },
379 &attr,385 &attr,
380 &io,386 &io,
381 null,387 null,
382 0,388 .{},
383 windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE | windows.FILE_SHARE_DELETE,389 .VALID_FLAGS,
384 windows.FILE_OPEN,390 .OPEN,
385 windows.FILE_DIRECTORY_FILE | windows.FILE_OPEN_FOR_BACKUP_INTENT,391 .{
392 .DIRECTORY_FILE = true,
393 .OPEN_FOR_BACKUP_INTENT = true,
394 },
386 null,395 null,
387 0,396 0,
388 )) {397 )) {
...@@ -437,13 +446,13 @@ const Os = switch (builtin.os.tag) {...@@ -437,13 +446,13 @@ const Os = switch (builtin.os.tag) {
437 fn getFileId(handle: windows.HANDLE) !FileId {446 fn getFileId(handle: windows.HANDLE) !FileId {
438 var file_id: FileId = undefined;447 var file_id: FileId = undefined;
439 var io_status: windows.IO_STATUS_BLOCK = undefined;448 var io_status: windows.IO_STATUS_BLOCK = undefined;
440 var volume_info: windows.FILE_FS_VOLUME_INFORMATION = undefined;449 var volume_info: windows.FILE.FS_VOLUME_INFORMATION = undefined;
441 switch (windows.ntdll.NtQueryVolumeInformationFile(450 switch (windows.ntdll.NtQueryVolumeInformationFile(
442 handle,451 handle,
443 &io_status,452 &io_status,
444 &volume_info,453 &volume_info,
445 @sizeOf(windows.FILE_FS_VOLUME_INFORMATION),454 @sizeOf(windows.FILE.FS_VOLUME_INFORMATION),
446 .FileFsVolumeInformation,455 .Volume,
447 )) {456 )) {
448 .SUCCESS => {},457 .SUCCESS => {},
449 // Buffer overflow here indicates that there is more information available than was able to be stored in the buffer458 // 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) {...@@ -453,13 +462,13 @@ const Os = switch (builtin.os.tag) {
453 else => |rc| return windows.unexpectedStatus(rc),462 else => |rc| return windows.unexpectedStatus(rc),
454 }463 }
455 file_id.volumeSerialNumber = volume_info.VolumeSerialNumber;464 file_id.volumeSerialNumber = volume_info.VolumeSerialNumber;
456 var internal_info: windows.FILE_INTERNAL_INFORMATION = undefined;465 var internal_info: windows.FILE.INTERNAL_INFORMATION = undefined;
457 switch (windows.ntdll.NtQueryInformationFile(466 switch (windows.ntdll.NtQueryInformationFile(
458 handle,467 handle,
459 &io_status,468 &io_status,
460 &internal_info,469 &internal_info,
461 @sizeOf(windows.FILE_INTERNAL_INFORMATION),470 @sizeOf(windows.FILE.INTERNAL_INFORMATION),
462 .FileInternalInformation,471 .Internal,
463 )) {472 )) {
464 .SUCCESS => {},473 .SUCCESS => {},
465 else => |rc| return windows.unexpectedStatus(rc),474 else => |rc| return windows.unexpectedStatus(rc),
lib/std/Io/Threaded.zig+100-70
...@@ -1301,8 +1301,11 @@ fn dirMakeWindows(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode...@@ -1301,8 +1301,11 @@ fn dirMakeWindows(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode
1301 _ = mode;1301 _ = mode;
1302 const sub_dir_handle = windows.OpenFile(sub_path_w.span(), .{1302 const sub_dir_handle = windows.OpenFile(sub_path_w.span(), .{
1303 .dir = dir.handle,1303 .dir = dir.handle,
1304 .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE,1304 .access_mask = .{
1305 .creation = windows.FILE_CREATE,1305 .GENERIC = .{ .READ = true },
1306 .STANDARD = .{ .SYNCHRONIZE = true },
1307 },
1308 .creation = .CREATE,
1306 .filter = .dir_only,1309 .filter = .dir_only,
1307 }) catch |err| switch (err) {1310 }) catch |err| switch (err) {
1308 error.IsDir => return error.Unexpected,1311 error.IsDir => return error.Unexpected,
...@@ -1370,9 +1373,6 @@ fn dirMakeOpenPathWindows(...@@ -1370,9 +1373,6 @@ fn dirMakeOpenPathWindows(
1370 const t: *Threaded = @ptrCast(@alignCast(userdata));1373 const t: *Threaded = @ptrCast(@alignCast(userdata));
1371 const current_thread = Thread.getCurrent(t);1374 const current_thread = Thread.getCurrent(t);
1372 const w = windows;1375 const w = windows;
1373 const access_mask = w.STANDARD_RIGHTS_READ | w.FILE_READ_ATTRIBUTES | w.FILE_READ_EA |
1374 w.SYNCHRONIZE | w.FILE_TRAVERSE |
1375 (if (options.iterate) w.FILE_LIST_DIRECTORY else @as(u32, 0));
13761376
1377 var it = std.fs.path.componentIterator(sub_path);1377 var it = std.fs.path.componentIterator(sub_path);
1378 // If there are no components in the path, then create a dummy component with the full path.1378 // If there are no components in the path, then create a dummy component with the full path.
...@@ -1387,7 +1387,7 @@ fn dirMakeOpenPathWindows(...@@ -1387,7 +1387,7 @@ fn dirMakeOpenPathWindows(
1387 const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, component.path);1387 const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, component.path);
1388 const sub_path_w = sub_path_w_array.span();1388 const sub_path_w = sub_path_w_array.span();
1389 const is_last = it.peekNext() == null;1389 const is_last = it.peekNext() == null;
1390 const create_disposition: u32 = if (is_last) w.FILE_OPEN_IF else w.FILE_CREATE;1390 const create_disposition: w.FILE.CREATE_DISPOSITION = if (is_last) .OPEN_IF else .CREATE;
13911391
1392 var result: Io.Dir = .{ .handle = undefined };1392 var result: Io.Dir = .{ .handle = undefined };
13931393
...@@ -1397,26 +1397,40 @@ fn dirMakeOpenPathWindows(...@@ -1397,26 +1397,40 @@ fn dirMakeOpenPathWindows(
1397 .MaximumLength = path_len_bytes,1397 .MaximumLength = path_len_bytes,
1398 .Buffer = @constCast(sub_path_w.ptr),1398 .Buffer = @constCast(sub_path_w.ptr),
1399 };1399 };
1400 var attr: w.OBJECT_ATTRIBUTES = .{
1401 .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
1402 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle,
1403 .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
1404 .ObjectName = &nt_name,
1405 .SecurityDescriptor = null,
1406 .SecurityQualityOfService = null,
1407 };
1408 const open_reparse_point: w.DWORD = if (!options.follow_symlinks) w.FILE_OPEN_REPARSE_POINT else 0x0;
1409 var io_status_block: w.IO_STATUS_BLOCK = undefined;1400 var io_status_block: w.IO_STATUS_BLOCK = undefined;
1410 const rc = w.ntdll.NtCreateFile(1401 const rc = w.ntdll.NtCreateFile(
1411 &result.handle,1402 &result.handle,
1412 access_mask,1403 .{
1413 &attr,1404 .SPECIFIC = .{ .FILE_DIRECTORY = .{
1405 .LIST = options.iterate,
1406 .READ_EA = true,
1407 .READ_ATTRIBUTES = true,
1408 .TRAVERSE = true,
1409 } },
1410 .STANDARD = .{
1411 .RIGHTS = .READ,
1412 .SYNCHRONIZE = true,
1413 },
1414 },
1415 &.{
1416 .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
1417 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle,
1418 .Attributes = .{},
1419 .ObjectName = &nt_name,
1420 .SecurityDescriptor = null,
1421 .SecurityQualityOfService = null,
1422 },
1414 &io_status_block,1423 &io_status_block,
1415 null,1424 null,
1416 w.FILE_ATTRIBUTE_NORMAL,1425 .{ .NORMAL = true },
1417 w.FILE_SHARE_READ | w.FILE_SHARE_WRITE | w.FILE_SHARE_DELETE,1426 .VALID_FLAGS,
1418 create_disposition,1427 create_disposition,
1419 w.FILE_DIRECTORY_FILE | w.FILE_SYNCHRONOUS_IO_NONALERT | w.FILE_OPEN_FOR_BACKUP_INTENT | open_reparse_point,1428 .{
1429 .DIRECTORY_FILE = true,
1430 .IO = .SYNCHRONOUS_NONALERT,
1431 .OPEN_FOR_BACKUP_INTENT = true,
1432 .OPEN_REPARSE_POINT = !options.follow_symlinks,
1433 },
1420 null,1434 null,
1421 0,1435 0,
1422 );1436 );
...@@ -1749,8 +1763,8 @@ fn fileStatWindows(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.Fi...@@ -1749,8 +1763,8 @@ fn fileStatWindows(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.Fi
1749 try current_thread.checkCancel();1763 try current_thread.checkCancel();
17501764
1751 var io_status_block: windows.IO_STATUS_BLOCK = undefined;1765 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
1752 var info: windows.FILE_ALL_INFORMATION = undefined;1766 var info: windows.FILE.ALL_INFORMATION = undefined;
1753 const rc = windows.ntdll.NtQueryInformationFile(file.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation);1767 const rc = windows.ntdll.NtQueryInformationFile(file.handle, &io_status_block, &info, @sizeOf(windows.FILE.ALL_INFORMATION), .All);
1754 switch (rc) {1768 switch (rc) {
1755 .SUCCESS => {},1769 .SUCCESS => {},
1756 // Buffer overflow here indicates that there is more information available than was able to be stored in the buffer1770 // 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...@@ -1765,9 +1779,9 @@ fn fileStatWindows(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.Fi
1765 .inode = info.InternalInformation.IndexNumber,1779 .inode = info.InternalInformation.IndexNumber,
1766 .size = @as(u64, @bitCast(info.StandardInformation.EndOfFile)),1780 .size = @as(u64, @bitCast(info.StandardInformation.EndOfFile)),
1767 .mode = 0,1781 .mode = 0,
1768 .kind = if (info.BasicInformation.FileAttributes & windows.FILE_ATTRIBUTE_REPARSE_POINT != 0) reparse_point: {1782 .kind = if (info.BasicInformation.FileAttributes.REPARSE_POINT) reparse_point: {
1769 var tag_info: windows.FILE_ATTRIBUTE_TAG_INFO = undefined;1783 var tag_info: windows.FILE.ATTRIBUTE_TAG_INFO = undefined;
1770 const tag_rc = windows.ntdll.NtQueryInformationFile(file.handle, &io_status_block, &tag_info, @sizeOf(windows.FILE_ATTRIBUTE_TAG_INFO), .FileAttributeTagInformation);1784 const tag_rc = windows.ntdll.NtQueryInformationFile(file.handle, &io_status_block, &tag_info, @sizeOf(windows.FILE.ATTRIBUTE_TAG_INFO), .AttributeTag);
1771 switch (tag_rc) {1785 switch (tag_rc) {
1772 .SUCCESS => {},1786 .SUCCESS => {},
1773 // INFO_LENGTH_MISMATCH and ACCESS_DENIED are the only documented possible errors1787 // 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...@@ -1776,12 +1790,10 @@ fn fileStatWindows(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.Fi
1776 .ACCESS_DENIED => return error.AccessDenied,1790 .ACCESS_DENIED => return error.AccessDenied,
1777 else => return windows.unexpectedStatus(rc),1791 else => return windows.unexpectedStatus(rc),
1778 }1792 }
1779 if (tag_info.ReparseTag & windows.reparse_tag_name_surrogate_bit != 0) {1793 if (tag_info.ReparseTag.IsSurrogate) break :reparse_point .sym_link;
1780 break :reparse_point .sym_link;
1781 }
1782 // Unknown reparse point1794 // Unknown reparse point
1783 break :reparse_point .unknown;1795 break :reparse_point .unknown;
1784 } else if (info.BasicInformation.FileAttributes & windows.FILE_ATTRIBUTE_DIRECTORY != 0)1796 } else if (info.BasicInformation.FileAttributes.DIRECTORY)
1785 .directory1797 .directory
1786 else1798 else
1787 .file,1799 .file,
...@@ -1983,15 +1995,15 @@ fn dirAccessWindows(...@@ -1983,15 +1995,15 @@ fn dirAccessWindows(
1983 .MaximumLength = path_len_bytes,1995 .MaximumLength = path_len_bytes,
1984 .Buffer = @constCast(sub_path_w.ptr),1996 .Buffer = @constCast(sub_path_w.ptr),
1985 };1997 };
1986 var attr = windows.OBJECT_ATTRIBUTES{1998 var attr: windows.OBJECT_ATTRIBUTES = .{
1987 .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),1999 .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
1988 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle,2000 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle,
1989 .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.2001 .Attributes = .{},
1990 .ObjectName = &nt_name,2002 .ObjectName = &nt_name,
1991 .SecurityDescriptor = null,2003 .SecurityDescriptor = null,
1992 .SecurityQualityOfService = null,2004 .SecurityQualityOfService = null,
1993 };2005 };
1994 var basic_info: windows.FILE_BASIC_INFORMATION = undefined;2006 var basic_info: windows.FILE.BASIC_INFORMATION = undefined;
1995 switch (windows.ntdll.NtQueryAttributesFile(&attr, &basic_info)) {2007 switch (windows.ntdll.NtQueryAttributesFile(&attr, &basic_info)) {
1996 .SUCCESS => return,2008 .SUCCESS => return,
1997 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,2009 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
...@@ -2187,16 +2199,21 @@ fn dirCreateFileWindows(...@@ -2187,16 +2199,21 @@ fn dirCreateFileWindows(
2187 const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, sub_path);2199 const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, sub_path);
2188 const sub_path_w = sub_path_w_array.span();2200 const sub_path_w = sub_path_w_array.span();
21892201
2190 const read_flag = if (flags.read) @as(u32, w.GENERIC_READ) else 0;
2191 const handle = try w.OpenFile(sub_path_w, .{2202 const handle = try w.OpenFile(sub_path_w, .{
2192 .dir = dir.handle,2203 .dir = dir.handle,
2193 .access_mask = w.SYNCHRONIZE | w.GENERIC_WRITE | read_flag,2204 .access_mask = .{
2205 .STANDARD = .{ .SYNCHRONIZE = true },
2206 .GENERIC = .{
2207 .WRITE = true,
2208 .READ = flags.read,
2209 },
2210 },
2194 .creation = if (flags.exclusive)2211 .creation = if (flags.exclusive)
2195 @as(u32, w.FILE_CREATE)2212 .CREATE
2196 else if (flags.truncate)2213 else if (flags.truncate)
2197 @as(u32, w.FILE_OVERWRITE_IF)2214 .OVERWRITE_IF
2198 else2215 else
2199 @as(u32, w.FILE_OPEN_IF),2216 .OPEN_IF,
2200 });2217 });
2201 errdefer w.CloseHandle(handle);2218 errdefer w.CloseHandle(handle);
2202 var io_status_block: w.IO_STATUS_BLOCK = undefined;2219 var io_status_block: w.IO_STATUS_BLOCK = undefined;
...@@ -2511,18 +2528,12 @@ pub fn dirOpenFileWtf16(...@@ -2511,18 +2528,12 @@ pub fn dirOpenFileWtf16(
2511 var attr: w.OBJECT_ATTRIBUTES = .{2528 var attr: w.OBJECT_ATTRIBUTES = .{
2512 .Length = @sizeOf(w.OBJECT_ATTRIBUTES),2529 .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
2513 .RootDirectory = dir_handle,2530 .RootDirectory = dir_handle,
2514 .Attributes = 0,2531 .Attributes = .{},
2515 .ObjectName = &nt_name,2532 .ObjectName = &nt_name,
2516 .SecurityDescriptor = null,2533 .SecurityDescriptor = null,
2517 .SecurityQualityOfService = null,2534 .SecurityQualityOfService = null,
2518 };2535 };
2519 var io_status_block: w.IO_STATUS_BLOCK = undefined;2536 var io_status_block: w.IO_STATUS_BLOCK = undefined;
2520 const blocking_flag: w.ULONG = w.FILE_SYNCHRONOUS_IO_NONALERT;
2521 const file_or_dir_flag: w.ULONG = w.FILE_NON_DIRECTORY_FILE;
2522 // If we're not following symlinks, we need to ensure we don't pass in any
2523 // synchronization flags such as FILE_SYNCHRONOUS_IO_NONALERT.
2524 const create_file_flags: w.ULONG = file_or_dir_flag |
2525 if (flags.follow_symlinks) blocking_flag else w.FILE_OPEN_REPARSE_POINT;
25262537
2527 // There are multiple kernel bugs being worked around with retries.2538 // There are multiple kernel bugs being worked around with retries.
2528 const max_attempts = 13;2539 const max_attempts = 13;
...@@ -2534,16 +2545,24 @@ pub fn dirOpenFileWtf16(...@@ -2534,16 +2545,24 @@ pub fn dirOpenFileWtf16(
2534 var result: w.HANDLE = undefined;2545 var result: w.HANDLE = undefined;
2535 const rc = w.ntdll.NtCreateFile(2546 const rc = w.ntdll.NtCreateFile(
2536 &result,2547 &result,
2537 w.SYNCHRONIZE |2548 .{
2538 (if (flags.isRead()) @as(u32, w.GENERIC_READ) else 0) |2549 .STANDARD = .{ .SYNCHRONIZE = true },
2539 (if (flags.isWrite()) @as(u32, w.GENERIC_WRITE) else 0),2550 .GENERIC = .{
2551 .READ = flags.isRead(),
2552 .WRITE = flags.isWrite(),
2553 },
2554 },
2540 &attr,2555 &attr,
2541 &io_status_block,2556 &io_status_block,
2542 null,2557 null,
2543 w.FILE_ATTRIBUTE_NORMAL,2558 .{ .NORMAL = true },
2544 w.FILE_SHARE_WRITE | w.FILE_SHARE_READ | w.FILE_SHARE_DELETE,2559 .VALID_FLAGS,
2545 w.FILE_OPEN,2560 .OPEN,
2546 create_file_flags,2561 .{
2562 .IO = if (flags.follow_symlinks) .SYNCHRONOUS_NONALERT else .ASYNCHRONOUS,
2563 .NON_DIRECTORY_FILE = true,
2564 .OPEN_REPARSE_POINT = !flags.follow_symlinks,
2565 },
2547 null,2566 null,
2548 0,2567 0,
2549 );2568 );
...@@ -2835,10 +2854,6 @@ pub fn dirOpenDirWindows(...@@ -2835,10 +2854,6 @@ pub fn dirOpenDirWindows(
2835) Io.Dir.OpenError!Io.Dir {2854) Io.Dir.OpenError!Io.Dir {
2836 const current_thread = Thread.getCurrent(t);2855 const current_thread = Thread.getCurrent(t);
2837 const w = windows;2856 const w = windows;
2838 // TODO remove some of these flags if options.access_sub_paths is false
2839 const base_flags = w.STANDARD_RIGHTS_READ | w.FILE_READ_ATTRIBUTES | w.FILE_READ_EA |
2840 w.SYNCHRONIZE | w.FILE_TRAVERSE;
2841 const access_mask: u32 = if (options.iterate) base_flags | w.FILE_LIST_DIRECTORY else base_flags;
28422857
2843 const path_len_bytes: u16 = @intCast(sub_path_w.len * 2);2858 const path_len_bytes: u16 = @intCast(sub_path_w.len * 2);
2844 var nt_name: w.UNICODE_STRING = .{2859 var nt_name: w.UNICODE_STRING = .{
...@@ -2846,28 +2861,43 @@ pub fn dirOpenDirWindows(...@@ -2846,28 +2861,43 @@ pub fn dirOpenDirWindows(
2846 .MaximumLength = path_len_bytes,2861 .MaximumLength = path_len_bytes,
2847 .Buffer = @constCast(sub_path_w.ptr),2862 .Buffer = @constCast(sub_path_w.ptr),
2848 };2863 };
2849 var attr: w.OBJECT_ATTRIBUTES = .{
2850 .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
2851 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle,
2852 .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
2853 .ObjectName = &nt_name,
2854 .SecurityDescriptor = null,
2855 .SecurityQualityOfService = null,
2856 };
2857 const open_reparse_point: w.DWORD = if (!options.follow_symlinks) w.FILE_OPEN_REPARSE_POINT else 0x0;
2858 var io_status_block: w.IO_STATUS_BLOCK = undefined;2864 var io_status_block: w.IO_STATUS_BLOCK = undefined;
2859 var result: Io.Dir = .{ .handle = undefined };2865 var result: Io.Dir = .{ .handle = undefined };
2860 try current_thread.checkCancel();2866 try current_thread.checkCancel();
2861 const rc = w.ntdll.NtCreateFile(2867 const rc = w.ntdll.NtCreateFile(
2862 &result.handle,2868 &result.handle,
2863 access_mask,2869 // TODO remove some of these flags if options.access_sub_paths is false
2864 &attr,2870 .{
2871 .SPECIFIC = .{ .FILE_DIRECTORY = .{
2872 .LIST = options.iterate,
2873 .READ_EA = true,
2874 .TRAVERSE = true,
2875 .READ_ATTRIBUTES = true,
2876 } },
2877 .STANDARD = .{
2878 .RIGHTS = .READ,
2879 .SYNCHRONIZE = true,
2880 },
2881 },
2882 &.{
2883 .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
2884 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle,
2885 .Attributes = .{},
2886 .ObjectName = &nt_name,
2887 .SecurityDescriptor = null,
2888 .SecurityQualityOfService = null,
2889 },
2865 &io_status_block,2890 &io_status_block,
2866 null,2891 null,
2867 w.FILE_ATTRIBUTE_NORMAL,2892 .{ .NORMAL = true },
2868 w.FILE_SHARE_READ | w.FILE_SHARE_WRITE | w.FILE_SHARE_DELETE,2893 .VALID_FLAGS,
2869 w.FILE_OPEN,2894 .OPEN,
2870 w.FILE_DIRECTORY_FILE | w.FILE_SYNCHRONOUS_IO_NONALERT | w.FILE_OPEN_FOR_BACKUP_INTENT | open_reparse_point,2895 .{
2896 .DIRECTORY_FILE = true,
2897 .IO = .SYNCHRONOUS_NONALERT,
2898 .OPEN_FOR_BACKUP_INTENT = true,
2899 .OPEN_REPARSE_POINT = !options.follow_symlinks,
2900 },
2871 null,2901 null,
2872 0,2902 0,
2873 );2903 );
lib/std/Thread.zig+12-15
...@@ -226,7 +226,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {...@@ -226,7 +226,7 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
226226
227 switch (windows.ntdll.NtSetInformationThread(227 switch (windows.ntdll.NtSetInformationThread(
228 self.getHandle(),228 self.getHandle(),
229 .ThreadNameInformation,229 .NameInformation,
230 &unicode_string,230 &unicode_string,
231 @sizeOf(windows.UNICODE_STRING),231 @sizeOf(windows.UNICODE_STRING),
232 )) {232 )) {
...@@ -338,7 +338,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co...@@ -338,7 +338,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
338338
339 switch (windows.ntdll.NtQueryInformationThread(339 switch (windows.ntdll.NtQueryInformationThread(
340 self.getHandle(),340 self.getHandle(),
341 .ThreadNameInformation,341 .NameInformation,
342 &buf,342 &buf,
343 buf_capacity,343 buf_capacity,
344 null,344 null,
...@@ -521,12 +521,10 @@ pub const YieldError = error{...@@ -521,12 +521,10 @@ pub const YieldError = error{
521521
522/// Yields the current thread potentially allowing other threads to run.522/// Yields the current thread potentially allowing other threads to run.
523pub fn yield() YieldError!void {523pub fn yield() YieldError!void {
524 if (native_os == .windows) {524 if (native_os == .windows) switch (windows.ntdll.NtYieldExecution()) {
525 // The return value has to do with how many other threads there are; it is not525 .SUCCESS, .NO_YIELD_PERFORMED => return,
526 // an error condition on Windows.526 else => return error.SystemCannotYield,
527 _ = windows.kernel32.SwitchToThread();527 };
528 return;
529 }
530 switch (posix.errno(posix.system.sched_yield())) {528 switch (posix.errno(posix.system.sched_yield())) {
531 .SUCCESS => return,529 .SUCCESS => return,
532 .NOSYS => return error.SystemCannotYield,530 .NOSYS => return error.SystemCannotYield,
...@@ -647,11 +645,11 @@ const WindowsThreadImpl = struct {...@@ -647,11 +645,11 @@ const WindowsThreadImpl = struct {
647 const ThreadCompletion = struct {645 const ThreadCompletion = struct {
648 completion: Completion,646 completion: Completion,
649 heap_ptr: windows.PVOID,647 heap_ptr: windows.PVOID,
650 heap_handle: windows.HANDLE,648 heap_handle: *windows.HEAP,
651 thread_handle: windows.HANDLE = undefined,649 thread_handle: windows.HANDLE = undefined,
652650
653 fn free(self: ThreadCompletion) void {651 fn free(self: ThreadCompletion) void {
654 const status = windows.kernel32.HeapFree(self.heap_handle, 0, self.heap_ptr);652 const status = windows.ntdll.RtlFreeHeap(self.heap_handle, .{}, self.heap_ptr);
655 assert(status != 0);653 assert(status != 0);
656 }654 }
657 };655 };
...@@ -673,10 +671,10 @@ const WindowsThreadImpl = struct {...@@ -673,10 +671,10 @@ const WindowsThreadImpl = struct {
673 }671 }
674 };672 };
675673
676 const heap_handle = windows.kernel32.GetProcessHeap() orelse return error.OutOfMemory;674 const heap_handle = windows.GetProcessHeap() orelse return error.OutOfMemory;
677 const alloc_bytes = @alignOf(Instance) + @sizeOf(Instance);675 const alloc_bytes = @alignOf(Instance) + @sizeOf(Instance);
678 const alloc_ptr = windows.ntdll.RtlAllocateHeap(heap_handle, 0, alloc_bytes) orelse return error.OutOfMemory;676 const alloc_ptr = windows.ntdll.RtlAllocateHeap(heap_handle, .{}, alloc_bytes) orelse return error.OutOfMemory;
679 errdefer assert(windows.kernel32.HeapFree(heap_handle, 0, alloc_ptr) != 0);677 errdefer assert(windows.ntdll.RtlFreeHeap(heap_handle, .{}, alloc_ptr) != 0);
680678
681 const instance_bytes = @as([*]u8, @ptrCast(alloc_ptr))[0..alloc_bytes];679 const instance_bytes = @as([*]u8, @ptrCast(alloc_ptr))[0..alloc_bytes];
682 var fba = std.heap.FixedBufferAllocator.init(instance_bytes);680 var fba = std.heap.FixedBufferAllocator.init(instance_bytes);
...@@ -693,8 +691,7 @@ const WindowsThreadImpl = struct {...@@ -693,8 +691,7 @@ const WindowsThreadImpl = struct {
693 // Windows appears to only support SYSTEM_INFO.dwAllocationGranularity minimum stack size.691 // Windows appears to only support SYSTEM_INFO.dwAllocationGranularity minimum stack size.
694 // Going lower makes it default to that specified in the executable (~1mb).692 // Going lower makes it default to that specified in the executable (~1mb).
695 // Its also fine if the limit here is incorrect as stack size is only a hint.693 // Its also fine if the limit here is incorrect as stack size is only a hint.
696 var stack_size = std.math.cast(u32, config.stack_size) orelse std.math.maxInt(u32);694 const stack_size = @max(64 * 1024, std.math.lossyCast(u32, config.stack_size));
697 stack_size = @max(64 * 1024, stack_size);
698695
699 instance.thread.thread_handle = windows.kernel32.CreateThread(696 instance.thread.thread_handle = windows.kernel32.CreateThread(
700 null,697 null,
lib/std/debug/SelfInfo/Windows.zig+14-8
...@@ -154,10 +154,10 @@ pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, context: *UnwindContext) Error...@@ -154,10 +154,10 @@ pub fn unwindFrame(si: *SelfInfo, gpa: Allocator, context: *UnwindContext) Error
154 _ = gpa;154 _ = gpa;
155155
156 const current_regs = context.cur.getRegs();156 const current_regs = context.cur.getRegs();
157 var image_base: windows.DWORD64 = undefined;157 var image_base: usize = undefined;
158 if (windows.ntdll.RtlLookupFunctionEntry(current_regs.ip, &image_base, &context.history_table)) |runtime_function| {158 if (windows.ntdll.RtlLookupFunctionEntry(current_regs.ip, &image_base, &context.history_table)) |runtime_function| {
159 var handler_data: ?*anyopaque = null;159 var handler_data: ?*anyopaque = null;
160 var establisher_frame: u64 = undefined;160 var establisher_frame: usize = undefined;
161 _ = windows.ntdll.RtlVirtualUnwind(161 _ = windows.ntdll.RtlVirtualUnwind(
162 windows.UNW_FLAG_NHANDLER,162 windows.UNW_FLAG_NHANDLER,
163 image_base,163 image_base,
...@@ -351,13 +351,19 @@ const Module = struct {...@@ -351,13 +351,19 @@ const Module = struct {
351 var section_handle: windows.HANDLE = undefined;351 var section_handle: windows.HANDLE = undefined;
352 const create_section_rc = windows.ntdll.NtCreateSection(352 const create_section_rc = windows.ntdll.NtCreateSection(
353 &section_handle,353 &section_handle,
354 windows.STANDARD_RIGHTS_REQUIRED | windows.SECTION_QUERY | windows.SECTION_MAP_READ,354 .{
355 .SPECIFIC = .{ .SECTION = .{
356 .QUERY = true,
357 .MAP_READ = true,
358 } },
359 .STANDARD = .{ .RIGHTS = .REQUIRED },
360 },
355 null,361 null,
356 null,362 null,
357 windows.PAGE_READONLY,363 .{ .READONLY = true },
358 // The documentation states that if no AllocationAttribute is specified, then SEC_COMMIT is the default.364 // The documentation states that if no AllocationAttribute is specified, then SEC_COMMIT is the default.
359 // In practice, this isn't the case and specifying 0 will result in INVALID_PARAMETER_6.365 // In practice, this isn't the case and specifying 0 will result in INVALID_PARAMETER_6.
360 windows.SEC_COMMIT,366 .{ .COMMIT = true },
361 coff_file.handle,367 coff_file.handle,
362 );368 );
363 if (create_section_rc != .SUCCESS) return error.MissingDebugInfo;369 if (create_section_rc != .SUCCESS) return error.MissingDebugInfo;
...@@ -372,9 +378,9 @@ const Module = struct {...@@ -372,9 +378,9 @@ const Module = struct {
372 0,378 0,
373 null,379 null,
374 &coff_len,380 &coff_len,
375 .ViewUnmap,381 .Unmap,
376 0,382 .{},
377 windows.PAGE_READONLY,383 .{ .READONLY = true },
378 );384 );
379 if (map_section_rc != .SUCCESS) return error.MissingDebugInfo;385 if (map_section_rc != .SUCCESS) return error.MissingDebugInfo;
380 errdefer assert(windows.ntdll.NtUnmapViewOfSection(process_handle, @constCast(section_view_ptr.?)) == .SUCCESS);386 errdefer assert(windows.ntdll.NtUnmapViewOfSection(process_handle, @constCast(section_view_ptr.?)) == .SUCCESS);
lib/std/enums.zig+3-1
...@@ -61,7 +61,9 @@ pub fn values(comptime E: type) []const E {...@@ -61,7 +61,9 @@ pub fn values(comptime E: type) []const E {
61/// panic when `e` has no tagged value.61/// panic when `e` has no tagged value.
62/// Returns the tag name for `e` or null if no tag exists.62/// Returns the tag name for `e` or null if no tag exists.
63pub fn tagName(comptime E: type, e: E) ?[:0]const u8 {63pub fn tagName(comptime E: type, e: E) ?[:0]const u8 {
64 return inline for (@typeInfo(E).@"enum".fields) |f| {64 const fields = @typeInfo(E).@"enum".fields;
65 @setEvalBranchQuota(fields.len);
66 return inline for (fields) |f| {
65 if (@intFromEnum(e) == f.value) break f.name;67 if (@intFromEnum(e) == f.value) break f.name;
66 } else null;68 } else null;
67}69}
lib/std/fs/Dir.zig+9-10
...@@ -453,10 +453,10 @@ pub const Iterator = switch (native_os) {...@@ -453,10 +453,10 @@ pub const Iterator = switch (native_os) {
453 &io,453 &io,
454 &self.buf,454 &self.buf,
455 self.buf.len,455 self.buf.len,
456 .FileBothDirectoryInformation,456 .BothDirectory,
457 w.FALSE,457 w.FALSE,
458 null,458 null,
459 if (self.first_iter) @as(w.BOOLEAN, w.TRUE) else @as(w.BOOLEAN, w.FALSE),459 @intFromBool(self.first_iter),
460 );460 );
461 self.first_iter = false;461 self.first_iter = false;
462 if (io.Information == 0) return null;462 if (io.Information == 0) return null;
...@@ -487,8 +487,8 @@ pub const Iterator = switch (native_os) {...@@ -487,8 +487,8 @@ pub const Iterator = switch (native_os) {
487 const name_wtf8 = self.name_data[0..name_wtf8_len];487 const name_wtf8 = self.name_data[0..name_wtf8_len];
488 const kind: Entry.Kind = blk: {488 const kind: Entry.Kind = blk: {
489 const attrs = dir_info.FileAttributes;489 const attrs = dir_info.FileAttributes;
490 if (attrs & w.FILE_ATTRIBUTE_DIRECTORY != 0) break :blk .directory;490 if (attrs.DIRECTORY) break :blk .directory;
491 if (attrs & w.FILE_ATTRIBUTE_REPARSE_POINT != 0) break :blk .sym_link;491 if (attrs.REPARSE_POINT) break :blk .sym_link;
492 break :blk .file;492 break :blk .file;
493 };493 };
494 return Entry{494 return Entry{
...@@ -1013,15 +1013,14 @@ pub fn realpathW(self: Dir, pathname: []const u16, out_buffer: []u8) RealPathErr...@@ -1013,15 +1013,14 @@ pub fn realpathW(self: Dir, pathname: []const u16, out_buffer: []u8) RealPathErr
1013pub fn realpathW2(self: Dir, pathname: []const u16, out_buffer: []u16) RealPathError![]u16 {1013pub fn realpathW2(self: Dir, pathname: []const u16, out_buffer: []u16) RealPathError![]u16 {
1014 const w = windows;1014 const w = windows;
10151015
1016 const access_mask = w.GENERIC_READ | w.SYNCHRONIZE;
1017 const share_access = w.FILE_SHARE_READ | w.FILE_SHARE_WRITE | w.FILE_SHARE_DELETE;
1018 const creation = w.FILE_OPEN;
1019 const h_file = blk: {1016 const h_file = blk: {
1020 const res = w.OpenFile(pathname, .{1017 const res = w.OpenFile(pathname, .{
1021 .dir = self.fd,1018 .dir = self.fd,
1022 .access_mask = access_mask,1019 .access_mask = .{
1023 .share_access = share_access,1020 .STANDARD = .{ .SYNCHRONIZE = true },
1024 .creation = creation,1021 .GENERIC = .{ .READ = true },
1022 },
1023 .creation = .OPEN,
1025 .filter = .any,1024 .filter = .any,
1026 }) catch |err| switch (err) {1025 }) catch |err| switch (err) {
1027 error.WouldBlock => unreachable,1026 error.WouldBlock => unreachable,
lib/std/fs/File.zig+7-7
...@@ -146,13 +146,13 @@ pub fn isCygwinPty(file: File) bool {...@@ -146,13 +146,13 @@ pub fn isCygwinPty(file: File) bool {
146 // for handles that aren't named pipes.146 // for handles that aren't named pipes.
147 {147 {
148 var io_status: windows.IO_STATUS_BLOCK = undefined;148 var io_status: windows.IO_STATUS_BLOCK = undefined;
149 var device_info: windows.FILE_FS_DEVICE_INFORMATION = undefined;149 var device_info: windows.FILE.FS_DEVICE_INFORMATION = undefined;
150 const rc = windows.ntdll.NtQueryVolumeInformationFile(handle, &io_status, &device_info, @sizeOf(windows.FILE_FS_DEVICE_INFORMATION), .FileFsDeviceInformation);150 const rc = windows.ntdll.NtQueryVolumeInformationFile(handle, &io_status, &device_info, @sizeOf(windows.FILE.FS_DEVICE_INFORMATION), .Device);
151 switch (rc) {151 switch (rc) {
152 .SUCCESS => {},152 .SUCCESS => {},
153 else => return false,153 else => return false,
154 }154 }
155 if (device_info.DeviceType != windows.FILE_DEVICE_NAMED_PIPE) return false;155 if (device_info.DeviceType.FileDevice != .NAMED_PIPE) return false;
156 }156 }
157157
158 const name_bytes_offset = @offsetOf(windows.FILE_NAME_INFO, "FileName");158 const name_bytes_offset = @offsetOf(windows.FILE_NAME_INFO, "FileName");
...@@ -166,7 +166,7 @@ pub fn isCygwinPty(file: File) bool {...@@ -166,7 +166,7 @@ pub fn isCygwinPty(file: File) bool {
166 var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (name_bytes_offset + num_name_bytes);166 var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (name_bytes_offset + num_name_bytes);
167167
168 var io_status_block: windows.IO_STATUS_BLOCK = undefined;168 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
169 const rc = windows.ntdll.NtQueryInformationFile(handle, &io_status_block, &name_info_bytes, @intCast(name_info_bytes.len), .FileNameInformation);169 const rc = windows.ntdll.NtQueryInformationFile(handle, &io_status_block, &name_info_bytes, @intCast(name_info_bytes.len), .Name);
170 switch (rc) {170 switch (rc) {
171 .SUCCESS => {},171 .SUCCESS => {},
172 .INVALID_PARAMETER => unreachable,172 .INVALID_PARAMETER => unreachable,
...@@ -485,7 +485,7 @@ pub fn setPermissions(self: File, permissions: Permissions) SetPermissionsError!...@@ -485,7 +485,7 @@ pub fn setPermissions(self: File, permissions: Permissions) SetPermissionsError!
485 &io_status_block,485 &io_status_block,
486 &info,486 &info,
487 @sizeOf(windows.FILE_BASIC_INFORMATION),487 @sizeOf(windows.FILE_BASIC_INFORMATION),
488 .FileBasicInformation,488 .Basic,
489 );489 );
490 switch (rc) {490 switch (rc) {
491 .SUCCESS => return,491 .SUCCESS => return,
...@@ -1324,7 +1324,7 @@ pub fn unlock(file: File) void {...@@ -1324,7 +1324,7 @@ pub fn unlock(file: File) void {
1324 &io_status_block,1324 &io_status_block,
1325 &range_off,1325 &range_off,
1326 &range_len,1326 &range_len,
1327 null,1327 0,
1328 ) catch |err| switch (err) {1328 ) catch |err| switch (err) {
1329 error.RangeNotLocked => unreachable, // Function assumes unlocked.1329 error.RangeNotLocked => unreachable, // Function assumes unlocked.
1330 error.Unexpected => unreachable, // Resource deallocation must succeed.1330 error.Unexpected => unreachable, // Resource deallocation must succeed.
...@@ -1415,7 +1415,7 @@ pub fn downgradeLock(file: File) LockError!void {...@@ -1415,7 +1415,7 @@ pub fn downgradeLock(file: File) LockError!void {
1415 &io_status_block,1415 &io_status_block,
1416 &range_off,1416 &range_off,
1417 &range_len,1417 &range_len,
1418 null,1418 0,
1419 ) catch |err| switch (err) {1419 ) catch |err| switch (err) {
1420 error.RangeNotLocked => unreachable, // File was not locked.1420 error.RangeNotLocked => unreachable, // File was not locked.
1421 error.Unexpected => unreachable, // Resource deallocation must succeed.1421 error.Unexpected => unreachable, // Resource deallocation must succeed.
lib/std/fs/test.zig+26-14
...@@ -256,13 +256,11 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" {...@@ -256,13 +256,11 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" {
256256
257 try setupSymlink(ctx.dir, dir_target_path, "symlink", .{ .is_directory = true });257 try setupSymlink(ctx.dir, dir_target_path, "symlink", .{ .is_directory = true });
258258
259 var symlink = switch (builtin.target.os.tag) {259 var symlink: Dir = switch (builtin.target.os.tag) {
260 .windows => windows_symlink: {260 .windows => windows_symlink: {
261 const sub_path_w = try windows.cStrToPrefixedFileW(ctx.dir.fd, "symlink");261 const sub_path_w = try windows.cStrToPrefixedFileW(ctx.dir.fd, "symlink");
262262
263 var result = Dir{263 var handle: windows.HANDLE = undefined;
264 .fd = undefined,
265 };
266264
267 const path_len_bytes = @as(u16, @intCast(sub_path_w.span().len * 2));265 const path_len_bytes = @as(u16, @intCast(sub_path_w.span().len * 2));
268 var nt_name = windows.UNICODE_STRING{266 var nt_name = windows.UNICODE_STRING{
...@@ -270,32 +268,46 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" {...@@ -270,32 +268,46 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" {
270 .MaximumLength = path_len_bytes,268 .MaximumLength = path_len_bytes,
271 .Buffer = @constCast(&sub_path_w.data),269 .Buffer = @constCast(&sub_path_w.data),
272 };270 };
273 var attr = windows.OBJECT_ATTRIBUTES{271 var attr: windows.OBJECT_ATTRIBUTES = .{
274 .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),272 .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
275 .RootDirectory = if (fs.path.isAbsoluteWindowsW(sub_path_w.span())) null else ctx.dir.fd,273 .RootDirectory = if (fs.path.isAbsoluteWindowsW(sub_path_w.span())) null else ctx.dir.fd,
276 .Attributes = 0,274 .Attributes = .{},
277 .ObjectName = &nt_name,275 .ObjectName = &nt_name,
278 .SecurityDescriptor = null,276 .SecurityDescriptor = null,
279 .SecurityQualityOfService = null,277 .SecurityQualityOfService = null,
280 };278 };
281 var io: windows.IO_STATUS_BLOCK = undefined;279 var io: windows.IO_STATUS_BLOCK = undefined;
282 const rc = windows.ntdll.NtCreateFile(280 const rc = windows.ntdll.NtCreateFile(
283 &result.fd,281 &handle,
284 windows.STANDARD_RIGHTS_READ | windows.FILE_READ_ATTRIBUTES | windows.FILE_READ_EA | windows.SYNCHRONIZE | windows.FILE_TRAVERSE,282 .{
283 .SPECIFIC = .{ .FILE_DIRECTORY = .{
284 .READ_EA = true,
285 .TRAVERSE = true,
286 .READ_ATTRIBUTES = true,
287 } },
288 .STANDARD = .{
289 .RIGHTS = .READ,
290 .SYNCHRONIZE = true,
291 },
292 },
285 &attr,293 &attr,
286 &io,294 &io,
287 null,295 null,
288 windows.FILE_ATTRIBUTE_NORMAL,296 .{ .NORMAL = true },
289 windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE | windows.FILE_SHARE_DELETE,297 .VALID_FLAGS,
290 windows.FILE_OPEN,298 .OPEN,
291 // FILE_OPEN_REPARSE_POINT is the important thing here299 .{
292 windows.FILE_OPEN_REPARSE_POINT | windows.FILE_DIRECTORY_FILE | windows.FILE_SYNCHRONOUS_IO_NONALERT | windows.FILE_OPEN_FOR_BACKUP_INTENT,300 .DIRECTORY_FILE = true,
301 .IO = .SYNCHRONOUS_NONALERT,
302 .OPEN_FOR_BACKUP_INTENT = true,
303 .OPEN_REPARSE_POINT = true, // the important thing here
304 },
293 null,305 null,
294 0,306 0,
295 );307 );
296308
297 switch (rc) {309 switch (rc) {
298 .SUCCESS => break :windows_symlink result,310 .SUCCESS => break :windows_symlink .{ .fd = handle },
299 else => return windows.unexpectedStatus(rc),311 else => return windows.unexpectedStatus(rc),
300 }312 }
301 },313 },
lib/std/heap/PageAllocator.zig+10-9
...@@ -30,7 +30,8 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {...@@ -30,7 +30,8 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
30 var base_addr: ?*anyopaque = null;30 var base_addr: ?*anyopaque = null;
31 var size: windows.SIZE_T = n;31 var size: windows.SIZE_T = n;
3232
33 var status = ntdll.NtAllocateVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), 0, &size, windows.MEM_COMMIT | windows.MEM_RESERVE, windows.PAGE_READWRITE);33 const current_process = windows.GetCurrentProcess();
34 var status = ntdll.NtAllocateVirtualMemory(current_process, @ptrCast(&base_addr), 0, &size, .{ .COMMIT = true, .RESERVE = true }, .{ .READWRITE = true });
3435
35 if (status == SUCCESS and mem.isAligned(@intFromPtr(base_addr), alignment_bytes)) {36 if (status == SUCCESS and mem.isAligned(@intFromPtr(base_addr), alignment_bytes)) {
36 return @ptrCast(base_addr);37 return @ptrCast(base_addr);
...@@ -38,7 +39,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {...@@ -38,7 +39,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
3839
39 if (status == SUCCESS) {40 if (status == SUCCESS) {
40 var region_size: windows.SIZE_T = 0;41 var region_size: windows.SIZE_T = 0;
41 _ = ntdll.NtFreeVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), &region_size, windows.MEM_RELEASE);42 _ = ntdll.NtFreeVirtualMemory(current_process, @ptrCast(&base_addr), &region_size, .{ .RELEASE = true });
42 }43 }
4344
44 const overalloc_len = n + alignment_bytes - page_size;45 const overalloc_len = n + alignment_bytes - page_size;
...@@ -47,7 +48,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {...@@ -47,7 +48,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
47 base_addr = null;48 base_addr = null;
48 size = overalloc_len;49 size = overalloc_len;
4950
50 status = ntdll.NtAllocateVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), 0, &size, windows.MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, windows.PAGE_NOACCESS);51 status = ntdll.NtAllocateVirtualMemory(current_process, @ptrCast(&base_addr), 0, &size, .{ .RESERVE = true, .RESERVE_PLACEHOLDER = true }, .{ .NOACCESS = true });
5152
52 if (status != SUCCESS) return null;53 if (status != SUCCESS) return null;
5354
...@@ -58,7 +59,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {...@@ -58,7 +59,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
58 if (prefix_size > 0) {59 if (prefix_size > 0) {
59 var prefix_base = base_addr;60 var prefix_base = base_addr;
60 var prefix_size_param: windows.SIZE_T = prefix_size;61 var prefix_size_param: windows.SIZE_T = prefix_size;
61 _ = ntdll.NtFreeVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&prefix_base), &prefix_size_param, windows.MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);62 _ = ntdll.NtFreeVirtualMemory(current_process, @ptrCast(&prefix_base), &prefix_size_param, .{ .RELEASE = true, .PRESERVE_PLACEHOLDER = true });
62 }63 }
6364
64 const suffix_start = aligned_addr + aligned_len;65 const suffix_start = aligned_addr + aligned_len;
...@@ -66,13 +67,13 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {...@@ -66,13 +67,13 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
66 if (suffix_size > 0) {67 if (suffix_size > 0) {
67 var suffix_base = @as(?*anyopaque, @ptrFromInt(suffix_start));68 var suffix_base = @as(?*anyopaque, @ptrFromInt(suffix_start));
68 var suffix_size_param: windows.SIZE_T = suffix_size;69 var suffix_size_param: windows.SIZE_T = suffix_size;
69 _ = ntdll.NtFreeVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&suffix_base), &suffix_size_param, windows.MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);70 _ = ntdll.NtFreeVirtualMemory(current_process, @ptrCast(&suffix_base), &suffix_size_param, .{ .RELEASE = true, .PRESERVE_PLACEHOLDER = true });
70 }71 }
7172
72 base_addr = @ptrFromInt(aligned_addr);73 base_addr = @ptrFromInt(aligned_addr);
73 size = aligned_len;74 size = aligned_len;
7475
75 status = ntdll.NtAllocateVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), 0, &size, windows.MEM_COMMIT | MEM_PRESERVE_PLACEHOLDER, windows.PAGE_READWRITE);76 status = ntdll.NtAllocateVirtualMemory(current_process, @ptrCast(&base_addr), 0, &size, .{ .COMMIT = true }, .{ .READWRITE = true });
7677
77 if (status == SUCCESS) {78 if (status == SUCCESS) {
78 return @ptrCast(base_addr);79 return @ptrCast(base_addr);
...@@ -80,7 +81,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {...@@ -80,7 +81,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
8081
81 base_addr = @as(?*anyopaque, @ptrFromInt(aligned_addr));82 base_addr = @as(?*anyopaque, @ptrFromInt(aligned_addr));
82 size = aligned_len;83 size = aligned_len;
83 _ = ntdll.NtFreeVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), &size, windows.MEM_RELEASE);84 _ = ntdll.NtFreeVirtualMemory(current_process, @ptrCast(&base_addr), &size, .{ .RELEASE = true });
8485
85 return null;86 return null;
86 }87 }
...@@ -145,7 +146,7 @@ pub fn unmap(memory: []align(page_size_min) u8) void {...@@ -145,7 +146,7 @@ pub fn unmap(memory: []align(page_size_min) u8) void {
145 if (native_os == .windows) {146 if (native_os == .windows) {
146 var base_addr: ?*anyopaque = memory.ptr;147 var base_addr: ?*anyopaque = memory.ptr;
147 var region_size: windows.SIZE_T = 0;148 var region_size: windows.SIZE_T = 0;
148 _ = ntdll.NtFreeVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), &region_size, windows.MEM_RELEASE);149 _ = ntdll.NtFreeVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&base_addr), &region_size, .{ .RELEASE = true });
149 } else {150 } else {
150 const page_aligned_len = mem.alignForward(usize, memory.len, std.heap.pageSize());151 const page_aligned_len = mem.alignForward(usize, memory.len, std.heap.pageSize());
151 posix.munmap(memory.ptr[0..page_aligned_len]);152 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 {...@@ -166,7 +167,7 @@ pub fn realloc(uncasted_memory: []u8, new_len: usize, may_move: bool) ?[*]u8 {
166 var decommit_addr: ?*anyopaque = @ptrFromInt(new_addr_end);167 var decommit_addr: ?*anyopaque = @ptrFromInt(new_addr_end);
167 var decommit_size: windows.SIZE_T = old_addr_end - new_addr_end;168 var decommit_size: windows.SIZE_T = old_addr_end - new_addr_end;
168169
169 _ = ntdll.NtAllocateVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&decommit_addr), 0, &decommit_size, windows.MEM_RESET, windows.PAGE_NOACCESS);170 _ = ntdll.NtAllocateVirtualMemory(windows.GetCurrentProcess(), @ptrCast(&decommit_addr), 0, &decommit_size, .{ .RESET = true }, .{ .NOACCESS = true });
170 }171 }
171 return memory.ptr;172 return memory.ptr;
172 }173 }
lib/std/os/windows.zig+2498-876
...@@ -28,9 +28,2265 @@ pub const ws2_32 = @import("windows/ws2_32.zig");...@@ -28,9 +28,2265 @@ pub const ws2_32 = @import("windows/ws2_32.zig");
28pub const crypt32 = @import("windows/crypt32.zig");28pub const crypt32 = @import("windows/crypt32.zig");
29pub const nls = @import("windows/nls.zig");29pub const nls = @import("windows/nls.zig");
3030
31pub const self_process_handle = @as(HANDLE, @ptrFromInt(maxInt(usize)));31pub const FILE = struct {
32 // ref: km/ntddk.h
3233
33const Self = @This();34 pub const END_OF_FILE_INFORMATION = extern struct {
35 EndOfFile: LARGE_INTEGER,
36 };
37
38 pub const ALIGNMENT_INFORMATION = extern struct {
39 AlignmentRequirement: ULONG,
40 };
41
42 pub const NAME_INFORMATION = extern struct {
43 FileNameLength: ULONG,
44 FileName: [1]WCHAR,
45 };
46
47 pub const DISPOSITION = packed struct(ULONG) {
48 DELETE: bool = false,
49 POSIX_SEMANTICS: bool = false,
50 FORCE_IMAGE_SECTION_CHECK: bool = false,
51 ON_CLOSE: bool = false,
52 IGNORE_READONLY_ATTRIBUTE: bool = false,
53 Reserved5: u27 = 0,
54
55 pub const DO_NOT_DELETE: DISPOSITION = .{};
56
57 pub const INFORMATION = extern struct {
58 DeleteFile: BOOLEAN,
59
60 pub const EX = extern struct {
61 Flags: DISPOSITION,
62 };
63 };
64 };
65
66 pub const FS_VOLUME_INFORMATION = extern struct {
67 VolumeCreationTime: LARGE_INTEGER,
68 VolumeSerialNumber: ULONG,
69 VolumeLabelLength: ULONG,
70 SupportsObjects: BOOLEAN,
71 VolumeLabel: [0]WCHAR,
72
73 pub fn getVolumeLabel(fvi: *const FS_VOLUME_INFORMATION) []const WCHAR {
74 return (&fvi).ptr[0..@divExact(fvi.VolumeLabelLength, @sizeOf(WCHAR))];
75 }
76 };
77
78 // ref: km/ntifs.h
79
80 pub const PIPE = struct {
81 /// Define the `NamedPipeType` flags for `NtCreateNamedPipeFile`
82 pub const TYPE = packed struct(ULONG) {
83 TYPE: enum(u1) {
84 BYTE_STREAM = 0b0,
85 MESSAGE = 0b1,
86 } = .BYTE_STREAM,
87 REMOTE_CLIENTS: enum(u1) {
88 ACCEPT = 0b0,
89 REJECT = 0b1,
90 } = .ACCEPT,
91 Reserved2: u30 = 0,
92
93 pub const VALID_MASK: TYPE = .{
94 .TYPE = .MESSAGE,
95 .REMOTE_CLIENTS = .REJECT,
96 };
97 };
98
99 /// Define the `CompletionMode` flags for `NtCreateNamedPipeFile`
100 pub const COMPLETION_MODE = packed struct(ULONG) {
101 OPERATION: enum(u1) {
102 QUEUE = 0b0,
103 COMPLETE = 0b1,
104 } = .QUEUE,
105 Reserved1: u31 = 0,
106 };
107
108 /// Define the `ReadMode` flags for `NtCreateNamedPipeFile`
109 pub const READ_MODE = packed struct(ULONG) {
110 MODE: enum(u1) {
111 BYTE_STREAM = 0b0,
112 MESSAGE = 0b1,
113 },
114 Reserved1: u31 = 0,
115 };
116
117 /// Define the `NamedPipeConfiguration` flags for `NtQueryInformationFile`
118 pub const CONFIGURATION = enum(ULONG) {
119 INBOUND = 0x00000000,
120 OUTBOUND = 0x00000001,
121 FULL_DUPLEX = 0x00000002,
122 };
123
124 /// Define the `NamedPipeState` flags for `NtQueryInformationFile`
125 pub const STATE = enum(ULONG) {
126 DISCONNECTED = 0x00000001,
127 LISTENING = 0x00000002,
128 CONNECTED = 0x00000003,
129 CLOSING = 0x00000004,
130 };
131
132 /// Define the `NamedPipeEnd` flags for `NtQueryInformationFile`
133 pub const END = enum(ULONG) {
134 CLIENT = 0x00000000,
135 SERVER = 0x00000001,
136 };
137
138 pub const INFORMATION = extern struct {
139 ReadMode: READ_MODE,
140 CompletionMode: COMPLETION_MODE,
141 };
142
143 pub const LOCAL_INFORMATION = extern struct {
144 NamedPipeType: TYPE,
145 NamedPipeConfiguration: CONFIGURATION,
146 MaximumInstances: ULONG,
147 CurrentInstances: ULONG,
148 InboundQuota: ULONG,
149 ReadDataAvailable: ULONG,
150 OutboundQuota: ULONG,
151 WriteQuotaAvailable: ULONG,
152 NamedPipeState: STATE,
153 NamedPipeEnd: END,
154 };
155
156 pub const REMOTE_INFORMATION = extern struct {
157 CollectDataTime: LARGE_INTEGER,
158 MaximumCollectionCount: ULONG,
159 };
160
161 pub const WAIT_FOR_BUFFER = extern struct {
162 Timeout: LARGE_INTEGER,
163 NameLength: ULONG,
164 TimeoutSpecified: BOOLEAN,
165 Name: [PATH_MAX_WIDE]WCHAR,
166
167 pub const WAIT_FOREVER: LARGE_INTEGER = std.math.minInt(LARGE_INTEGER);
168
169 pub fn init(opts: struct {
170 Timeout: ?LARGE_INTEGER = null,
171 Name: []const WCHAR,
172 }) WAIT_FOR_BUFFER {
173 var fpwfb: WAIT_FOR_BUFFER = .{
174 .Timeout = opts.Timeout orelse undefined,
175 .NameLength = @intCast(@sizeOf(WCHAR) * opts.Name.len),
176 .TimeoutSpecified = @intFromBool(opts.Timeout != null),
177 .Name = undefined,
178 };
179 @memcpy(fpwfb.Name[0..opts.Name.len], opts.Name);
180 return fpwfb;
181 }
182
183 pub fn getName(fpwfb: *const WAIT_FOR_BUFFER) []const WCHAR {
184 return fpwfb.Name[0..@divExact(fpwfb.NameLength, @sizeOf(WCHAR))];
185 }
186
187 pub fn toBuffer(fpwfb: *const WAIT_FOR_BUFFER) []const u8 {
188 const start: [*]const u8 = @ptrCast(fpwfb);
189 return start[0 .. @offsetOf(WAIT_FOR_BUFFER, "Name") + fpwfb.NameLength];
190 }
191 };
192 };
193
194 pub const ALL_INFORMATION = extern struct {
195 BasicInformation: BASIC_INFORMATION,
196 StandardInformation: STANDARD_INFORMATION,
197 InternalInformation: INTERNAL_INFORMATION,
198 EaInformation: EA_INFORMATION,
199 AccessInformation: ACCESS_INFORMATION,
200 PositionInformation: POSITION_INFORMATION,
201 ModeInformation: MODE.INFORMATION,
202 AlignmentInformation: ALIGNMENT_INFORMATION,
203 NameInformation: NAME_INFORMATION,
204 };
205
206 pub const INTERNAL_INFORMATION = extern struct {
207 IndexNumber: LARGE_INTEGER,
208 };
209
210 pub const EA_INFORMATION = extern struct {
211 EaSize: ULONG,
212 };
213
214 pub const ACCESS_INFORMATION = extern struct {
215 AccessFlags: ACCESS_MASK,
216 };
217
218 pub const RENAME_INFORMATION = extern struct {
219 Flags: FLAGS,
220 RootDirectory: ?HANDLE,
221 FileNameLength: ULONG,
222 FileName: [PATH_MAX_WIDE]WCHAR,
223
224 pub fn init(opts: struct {
225 Flags: FLAGS = .{},
226 RootDirectory: ?HANDLE = null,
227 FileName: []const WCHAR,
228 }) RENAME_INFORMATION {
229 var fri: RENAME_INFORMATION = .{
230 .Flags = opts.Flags,
231 .RootDirectory = opts.RootDirectory,
232 .FileNameLength = @intCast(@sizeOf(WCHAR) * opts.FileName.len),
233 .FileName = undefined,
234 };
235 @memcpy(fri.FileName[0..opts.FileName.len], opts.FileName);
236 return fri;
237 }
238
239 pub const FLAGS = packed struct(ULONG) {
240 REPLACE_IF_EXISTS: bool = false,
241 POSIX_SEMANTICS: bool = false,
242 SUPPRESS_PIN_STATE_INHERITANCE: bool = false,
243 SUPPRESS_STORAGE_RESERVE_INHERITANCE: bool = false,
244 AVAILABLE_SPACE: enum(u2) {
245 NO_PRESERVE = 0b00,
246 NO_INCREASE = 0b01,
247 NO_DECREASE = 0b10,
248 PRESERVE = 0b11,
249 } = .NO_PRESERVE,
250 IGNORE_READONLY_ATTRIBUTE: bool = false,
251 RESIZE_SR: enum(u2) {
252 NO_FORCE = 0b00,
253 FORCE_TARGET = 0b01,
254 FORCE_SOURCE = 0b10,
255 FORCE = 0b11,
256 } = .NO_FORCE,
257 Reserved9: u23 = 0,
258 };
259
260 pub fn getFileName(ri: *const RENAME_INFORMATION) []const WCHAR {
261 return ri.FileName[0..@divExact(ri.FileNameLength, @sizeOf(WCHAR))];
262 }
263
264 pub fn toBuffer(fri: *const RENAME_INFORMATION) []const u8 {
265 const start: [*]const u8 = @ptrCast(fri);
266 return start[0 .. @offsetOf(RENAME_INFORMATION, "FileName") + fri.FileNameLength];
267 }
268 };
269
270 // ref: km/wdm.h
271
272 pub const INFORMATION_CLASS = enum(c_int) {
273 Directory = 1,
274 FullDirectory = 2,
275 BothDirectory = 3,
276 Basic = 4,
277 Standard = 5,
278 Internal = 6,
279 Ea = 7,
280 Access = 8,
281 Name = 9,
282 Rename = 10,
283 Link = 11,
284 Names = 12,
285 Disposition = 13,
286 Position = 14,
287 FullEa = 15,
288 Mode = 16,
289 Alignment = 17,
290 All = 18,
291 Allocation = 19,
292 EndOfFile = 20,
293 AlternateName = 21,
294 Stream = 22,
295 Pipe = 23,
296 PipeLocal = 24,
297 PipeRemote = 25,
298 MailslotQuery = 26,
299 MailslotSet = 27,
300 Compression = 28,
301 ObjectId = 29,
302 Completion = 30,
303 MoveCluster = 31,
304 Quota = 32,
305 ReparsePoint = 33,
306 NetworkOpen = 34,
307 AttributeTag = 35,
308 Tracking = 36,
309 IdBothDirectory = 37,
310 IdFullDirectory = 38,
311 ValidDataLength = 39,
312 ShortName = 40,
313 IoCompletionNotification = 41,
314 IoStatusBlockRange = 42,
315 IoPriorityHint = 43,
316 SfioReserve = 44,
317 SfioVolume = 45,
318 HardLink = 46,
319 ProcessIdsUsingFile = 47,
320 NormalizedName = 48,
321 NetworkPhysicalName = 49,
322 IdGlobalTxDirectory = 50,
323 IsRemoteDevice = 51,
324 Unused = 52,
325 NumaNode = 53,
326 StandardLink = 54,
327 RemoteProtocol = 55,
328 RenameBypassAccessCheck = 56,
329 LinkBypassAccessCheck = 57,
330 VolumeName = 58,
331 Id = 59,
332 IdExtdDirectory = 60,
333 ReplaceCompletion = 61,
334 HardLinkFullId = 62,
335 IdExtdBothDirectory = 63,
336 DispositionEx = 64,
337 RenameEx = 65,
338 RenameExBypassAccessCheck = 66,
339 DesiredStorageClass = 67,
340 Stat = 68,
341 MemoryPartition = 69,
342 StatLx = 70,
343 CaseSensitive = 71,
344 LinkEx = 72,
345 LinkExBypassAccessCheck = 73,
346 StorageReserveId = 74,
347 CaseSensitiveForceAccessCheck = 75,
348 KnownFolder = 76,
349 StatBasic = 77,
350 Id64ExtdDirectory = 78,
351 Id64ExtdBothDirectory = 79,
352 IdAllExtdDirectory = 80,
353 IdAllExtdBothDirectory = 81,
354 StreamReservation = 82,
355 MupProvider = 83,
356
357 pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".fields.len;
358 };
359
360 pub const BASIC_INFORMATION = extern struct {
361 CreationTime: LARGE_INTEGER,
362 LastAccessTime: LARGE_INTEGER,
363 LastWriteTime: LARGE_INTEGER,
364 ChangeTime: LARGE_INTEGER,
365 FileAttributes: ATTRIBUTE,
366 };
367
368 pub const STANDARD_INFORMATION = extern struct {
369 AllocationSize: LARGE_INTEGER,
370 EndOfFile: LARGE_INTEGER,
371 NumberOfLinks: ULONG,
372 DeletePending: BOOLEAN,
373 Directory: BOOLEAN,
374 };
375
376 pub const POSITION_INFORMATION = extern struct {
377 CurrentByteOffset: LARGE_INTEGER,
378 };
379
380 pub const FS_DEVICE_INFORMATION = extern struct {
381 DeviceType: DEVICE_TYPE,
382 Characteristics: ULONG,
383 };
384
385 // ref: um/WinBase.h
386
387 pub const ATTRIBUTE_TAG_INFO = extern struct {
388 FileAttributes: DWORD,
389 ReparseTag: IO_REPARSE_TAG,
390 };
391
392 // ref: um/winnt.h
393
394 pub const SHARE = packed struct(ULONG) {
395 /// The file can be opened for read access by other threads.
396 READ: bool = false,
397 /// The file can be opened for write access by other threads.
398 WRITE: bool = false,
399 /// The file can be opened for delete access by other threads.
400 DELETE: bool = false,
401 Reserved3: u29 = 0,
402
403 pub const VALID_FLAGS: SHARE = .{
404 .READ = true,
405 .WRITE = true,
406 .DELETE = true,
407 };
408 };
409
410 pub const ATTRIBUTE = packed struct(ULONG) {
411 /// The file is read only. Applications can read the file, but cannot write to or delete it.
412 READONLY: bool = false,
413 /// The file is hidden. Do not include it in an ordinary directory listing.
414 HIDDEN: bool = false,
415 /// The file is part of or used exclusively by an operating system.
416 SYSTEM: bool = false,
417 Reserved3: u1 = 0,
418 DIRECTORY: bool = false,
419 /// The file should be archived. Applications use this attribute to mark files for backup or removal.
420 ARCHIVE: bool = false,
421 DEVICE: bool = false,
422 /// The file does not have other attributes set. This attribute is valid only if used alone.
423 NORMAL: bool = false,
424 /// The file is being used for temporary storage.
425 TEMPORARY: bool = false,
426 SPARSE_FILE: bool = false,
427 REPARSE_POINT: bool = false,
428 COMPRESSED: bool = false,
429 /// The data of a file is not immediately available. This attribute indicates that file data is physically moved to offline storage.
430 /// This attribute is used by Remote Storage, the hierarchical storage management software. Applications should not arbitrarily change this attribute.
431 OFFLINE: bool = false,
432 NOT_CONTENT_INDEXED: bool = false,
433 /// 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
434 /// the default for newly created files and subdirectories. For more information, see File Encryption.
435 ///
436 /// This flag has no effect if `SYSTEM` is also specified.
437 ///
438 /// This flag is not supported on Home, Home Premium, Starter, or ARM editions of Windows.
439 ENCRYPTED: bool = false,
440 INTEGRITY_STREAM: bool = false,
441 VIRTUAL: bool = false,
442 NO_SCRUB_DATA: bool = false,
443 EA_or_RECALL_ON_OPEN: bool = false,
444 PINNED: bool = false,
445 UNPINNED: bool = false,
446 Reserved21: u1 = 0,
447 RECALL_ON_DATA_ACCESS: bool = false,
448 Reserved23: u6 = 0,
449 STRICTLY_SEQUENTIAL: bool = false,
450 Reserved30: u2 = 0,
451 };
452
453 // ref: um/winternl.h
454
455 /// Define the create disposition values
456 pub const CREATE_DISPOSITION = enum(ULONG) {
457 /// If the file already exists, replace it with the given file. If it does not, create the given file.
458 SUPERSEDE = 0x00000000,
459 /// 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.
460 OPEN = 0x00000001,
461 /// 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.
462 CREATE = 0x00000002,
463 /// If the file already exists, open it. If it does not, create the given file.
464 OPEN_IF = 0x00000003,
465 /// If the file already exists, open it and overwrite it. If it does not, fail the request.
466 OVERWRITE = 0x00000004,
467 /// If the file already exists, open it and overwrite it. If it does not, create the given file.
468 OVERWRITE_IF = 0x00000005,
469
470 pub const MAXIMUM_DISPOSITION: CREATE_DISPOSITION = .OVERWRITE_IF;
471 };
472
473 /// Define the create/open option flags
474 pub const MODE = packed struct(ULONG) {
475 /// 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`.
476 /// With this flag, other compatible CreateOptions flags include only the following: `SYNCHRONOUS_IO`, `WRITE_THROUGH`, `OPEN_FOR_BACKUP_INTENT`, and `OPEN_BY_FILE_ID`.
477 DIRECTORY_FILE: bool = false,
478 /// Applications that write data to the file must actually transfer the data into the file before any requested write operation is considered complete.
479 /// This flag is automatically set if the CreateOptions flag `NO_INTERMEDIATE_BUFFERING` is set.
480 WRITE_THROUGH: bool = false,
481 /// All accesses to the file are sequential.
482 SEQUENTIAL_ONLY: bool = false,
483 /// The file cannot be cached or buffered in a driver's internal buffers. This flag is incompatible with the DesiredAccess `FILE_APPEND_DATA` flag.
484 NO_INTERMEDIATE_BUFFERING: bool = false,
485 IO: enum(u2) {
486 /// All operations on the file are performed asynchronously.
487 ASYNCHRONOUS = 0b00,
488 /// All operations on the file are performed synchronously. Any wait on behalf of the caller is subject to premature termination from alerts.
489 /// 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.
490 SYNCHRONOUS_ALERT = 0b01,
491 /// All operations on the file are performed synchronously. Waits in the system to synchronize I/O queuing and completion are not subject to alerts.
492 /// 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.
493 SYNCHRONOUS_NONALERT = 0b10,
494 _,
495
496 pub const VALID_FLAGS: @This() = @enumFromInt(0b11);
497 } = .ASYNCHRONOUS,
498 /// 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
499 /// device, or a volume.
500 NON_DIRECTORY_FILE: bool = false,
501 /// 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.
502 CREATE_TREE_CONNECTION: bool = false,
503 /// Complete this operation immediately with an alternate success code of `STATUS_OPLOCK_BREAK_IN_PROGRESS` if the target file is oplocked, rather than blocking
504 /// 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.
505 COMPLETE_IF_OPLOCKED: bool = false,
506 /// 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
507 /// because the caller does not understand how to deal with EAs. This flag is irrelevant for device and intermediate drivers.
508 NO_EA_KNOWLEDGE: bool = false,
509 OPEN_REMOTE_INSTANCE: bool = false,
510 /// Accesses to the file can be random, so no sequential read-ahead operations should be performed on the file by FSDs or the system.
511 RANDOM_ACCESS: bool = false,
512 /// 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.
513 DELETE_ON_CLOSE: bool = false,
514 /// 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
515 /// 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
516 /// does not support this flag. This flag is not used by device and intermediate drivers.
517 OPEN_BY_FILE_ID: bool = false,
518 /// 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
519 /// file before checking the DesiredAccess parameter against the file's security descriptor. This flag not used by device and intermediate drivers.
520 OPEN_FOR_BACKUP_INTENT: bool = false,
521 /// Suppress inheritance of `FILE_ATTRIBUTE.COMPRESSED` from the parent directory. This allows creation of a non-compressed file in a directory that is marked
522 /// compressed.
523 NO_COMPRESSION: bool = false,
524 /// 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
525 /// 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.
526 /// For more information, see the Remarks section.
527 ///
528 /// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This flag is not supported.
529 ///
530 /// This flag is supported on the following file systems: NTFS, FAT, and exFAT.
531 OPEN_REQUIRING_OPLOCK: bool = false,
532 Reserved17: u3 = 0,
533 /// This flag allows an application to request a filter opportunistic lock to prevent other applications from getting share violations. If there are already open
534 /// handles, the create request will fail with STATUS_OPLOCK_NOT_GRANTED. For more information, see the Remarks section.
535 RESERVE_OPFILTER: bool = false,
536 /// Open a file with a reparse point and bypass normal reparse point processing for the file. For more information, see the Remarks section.
537 OPEN_REPARSE_POINT: bool = false,
538 /// Instructs any filters that perform offline storage or virtualization to not recall the contents of the file as a result of this open.
539 OPEN_NO_RECALL: bool = false,
540 /// This flag instructs the file system to capture the user associated with the calling thread. Any subsequent calls to `FltQueryVolumeInformation` or
541 /// `ZwQueryVolumeInformationFile` using the returned handle will assume the captured user, rather than the calling user at the time, for purposes of computing
542 /// the free space available to the caller. This applies to the following FsInformationClass values: `FileFsSizeInformation`, `FileFsFullSizeInformation`, and
543 /// `FileFsFullSizeInformationEx`.
544 OPEN_FOR_FREE_SPACE_QUERY: bool = false,
545 Reserved24: u8 = 0,
546
547 pub const VALID_OPTION_FLAGS: MODE = .{
548 .DIRECTORY_FILE = true,
549 .WRITE_THROUGH = true,
550 .SEQUENTIAL_ONLY = true,
551 .NO_INTERMEDIATE_BUFFERING = true,
552 .IO = .VALID_FLAGS,
553 .NON_DIRECTORY_FILE = true,
554 .CREATE_TREE_CONNECTION = true,
555 .COMPLETE_IF_OPLOCKED = true,
556 .NO_EA_KNOWLEDGE = true,
557 .OPEN_REMOTE_INSTANCE = true,
558 .RANDOM_ACCESS = true,
559 .DELETE_ON_CLOSE = true,
560 .OPEN_BY_FILE_ID = true,
561 .OPEN_FOR_BACKUP_INTENT = true,
562 .NO_COMPRESSION = true,
563 .OPEN_REQUIRING_OPLOCK = true,
564 .Reserved17 = 0b111,
565 .RESERVE_OPFILTER = true,
566 .OPEN_REPARSE_POINT = true,
567 .OPEN_NO_RECALL = true,
568 .OPEN_FOR_FREE_SPACE_QUERY = true,
569 };
570
571 pub const VALID_PIPE_OPTION_FLAGS: MODE = .{
572 .WRITE_THROUGH = true,
573 .IO = .VALID_FLAGS,
574 };
575
576 pub const VALID_MAILSLOT_OPTION_FLAGS: MODE = .{
577 .WRITE_THROUGH = true,
578 .IO = .VALID_FLAGS,
579 };
580
581 pub const VALID_SET_OPTION_FLAGS: MODE = .{
582 .WRITE_THROUGH = true,
583 .SEQUENTIAL_ONLY = true,
584 .IO = .VALID_FLAGS,
585 };
586
587 // ref: km/ntifs.h
588
589 pub const INFORMATION = extern struct {
590 /// The set of flags that specify the mode in which the file can be accessed. These flags are a subset of `MODE`.
591 Mode: MODE,
592 };
593 };
594};
595
596// ref: km/ntddk.h
597
598pub const PROCESSINFOCLASS = enum(c_int) {
599 BasicInformation = 0,
600 QuotaLimits = 1,
601 IoCounters = 2,
602 VmCounters = 3,
603 Times = 4,
604 BasePriority = 5,
605 RaisePriority = 6,
606 DebugPort = 7,
607 ExceptionPort = 8,
608 AccessToken = 9,
609 LdtInformation = 10,
610 LdtSize = 11,
611 DefaultHardErrorMode = 12,
612 IoPortHandlers = 13,
613 PooledUsageAndLimits = 14,
614 WorkingSetWatch = 15,
615 UserModeIOPL = 16,
616 EnableAlignmentFaultFixup = 17,
617 PriorityClass = 18,
618 Wx86Information = 19,
619 HandleCount = 20,
620 AffinityMask = 21,
621 PriorityBoost = 22,
622 DeviceMap = 23,
623 SessionInformation = 24,
624 ForegroundInformation = 25,
625 Wow64Information = 26,
626 ImageFileName = 27,
627 LUIDDeviceMapsEnabled = 28,
628 BreakOnTermination = 29,
629 DebugObjectHandle = 30,
630 DebugFlags = 31,
631 HandleTracing = 32,
632 IoPriority = 33,
633 ExecuteFlags = 34,
634 TlsInformation = 35,
635 Cookie = 36,
636 ImageInformation = 37,
637 CycleTime = 38,
638 PagePriority = 39,
639 InstrumentationCallback = 40,
640 ThreadStackAllocation = 41,
641 WorkingSetWatchEx = 42,
642 ImageFileNameWin32 = 43,
643 ImageFileMapping = 44,
644 AffinityUpdateMode = 45,
645 MemoryAllocationMode = 46,
646 GroupInformation = 47,
647 TokenVirtualizationEnabled = 48,
648 OwnerInformation = 49,
649 WindowInformation = 50,
650 HandleInformation = 51,
651 MitigationPolicy = 52,
652 DynamicFunctionTableInformation = 53,
653 HandleCheckingMode = 54,
654 KeepAliveCount = 55,
655 RevokeFileHandles = 56,
656 WorkingSetControl = 57,
657 HandleTable = 58,
658 CheckStackExtentsMode = 59,
659 CommandLineInformation = 60,
660 ProtectionInformation = 61,
661 MemoryExhaustion = 62,
662 FaultInformation = 63,
663 TelemetryIdInformation = 64,
664 CommitReleaseInformation = 65,
665 Reserved1Information = 66,
666 Reserved2Information = 67,
667 SubsystemProcess = 68,
668 InPrivate = 70,
669 RaiseUMExceptionOnInvalidHandleClose = 71,
670 SubsystemInformation = 75,
671 Win32kSyscallFilterInformation = 79,
672 EnergyTrackingState = 82,
673 NetworkIoCounters = 114,
674 _,
675
676 pub const Max: @typeInfo(@This()).@"enum".tag_type = 117;
677};
678
679pub const THREADINFOCLASS = enum(c_int) {
680 BasicInformation = 0,
681 Times = 1,
682 Priority = 2,
683 BasePriority = 3,
684 AffinityMask = 4,
685 ImpersonationToken = 5,
686 DescriptorTableEntry = 6,
687 EnableAlignmentFaultFixup = 7,
688 EventPair_Reusable = 8,
689 QuerySetWin32StartAddress = 9,
690 ZeroTlsCell = 10,
691 PerformanceCount = 11,
692 AmILastThread = 12,
693 IdealProcessor = 13,
694 PriorityBoost = 14,
695 SetTlsArrayAddress = 15,
696 IsIoPending = 16,
697 // Windows 2000+ from here
698 HideFromDebugger = 17,
699 // Windows XP+ from here
700 BreakOnTermination = 18,
701 SwitchLegacyState = 19,
702 IsTerminated = 20,
703 // Windows Vista+ from here
704 LastSystemCall = 21,
705 IoPriority = 22,
706 CycleTime = 23,
707 PagePriority = 24,
708 ActualBasePriority = 25,
709 TebInformation = 26,
710 CSwitchMon = 27,
711 // Windows 7+ from here
712 CSwitchPmu = 28,
713 Wow64Context = 29,
714 GroupInformation = 30,
715 UmsInformation = 31,
716 CounterProfiling = 32,
717 IdealProcessorEx = 33,
718 // Windows 8+ from here
719 CpuAccountingInformation = 34,
720 // Windows 8.1+ from here
721 SuspendCount = 35,
722 // Windows 10+ from here
723 HeterogeneousCpuPolicy = 36,
724 ContainerId = 37,
725 NameInformation = 38,
726 SelectedCpuSets = 39,
727 SystemThreadInformation = 40,
728 ActualGroupAffinity = 41,
729 DynamicCodePolicyInfo = 42,
730 SubsystemInformation = 45,
731
732 pub const Max: @typeInfo(@This()).@"enum".tag_type = 60;
733};
734
735// ref: km/ntifs.h
736
737pub const HEAP = opaque {
738 pub const FLAGS = packed struct(u8) {
739 /// Serialized access is not used when the heap functions access this heap. This option
740 /// applies to all subsequent heap function calls. Alternatively, you can specify this
741 /// option on individual heap function calls.
742 ///
743 /// The low-fragmentation heap (LFH) cannot be enabled for a heap created with this option.
744 ///
745 /// A heap created with this option cannot be locked.
746 NO_SERIALIZE: bool = false,
747 /// Specifies that the heap is growable. Must be specified if `HeapBase` is `NULL`.
748 GROWABLE: bool = false,
749 /// The system raises an exception to indicate failure (for example, an out-of-memory
750 /// condition) for calls to `HeapAlloc` and `HeapReAlloc` instead of returning `NULL`.
751 ///
752 /// To ensure that exceptions are generated for all calls to an allocation function, specify
753 /// `GENERATE_EXCEPTIONS` in the call to `HeapCreate`. In this case, it is not necessary to
754 /// additionally specify `GENERATE_EXCEPTIONS` in the allocation function calls.
755 GENERATE_EXCEPTIONS: bool = false,
756 /// The allocated memory will be initialized to zero. Otherwise, the memory is not
757 /// initialized to zero.
758 ZERO_MEMORY: bool = false,
759 REALLOC_IN_PLACE_ONLY: bool = false,
760 TAIL_CHECKING_ENABLED: bool = false,
761 FREE_CHECKING_ENABLED: bool = false,
762 DISABLE_COALESCE_ON_FREE: bool = false,
763
764 pub const CLASS = enum(u4) {
765 /// process heap
766 PROCESS,
767 /// private heap
768 PRIVATE,
769 /// Kernel Heap
770 KERNEL,
771 /// GDI heap
772 GDI,
773 /// User heap
774 USER,
775 /// Console heap
776 CONSOLE,
777 /// User Desktop heap
778 USER_DESKTOP,
779 /// Csrss Shared heap
780 CSRSS_SHARED,
781 /// Csr Port heap
782 CSR_PORT,
783 _,
784
785 pub const MASK: CLASS = @enumFromInt(maxInt(@typeInfo(CLASS).@"enum".tag_type));
786 };
787
788 pub const CREATE = packed struct(ULONG) {
789 COMMON: FLAGS = .{},
790 SEGMENT_HEAP: bool = false,
791 /// Only applies to segment heap. Applies pointer obfuscation which is
792 /// generally excessive and unnecessary but is necessary for certain insecure
793 /// heaps in win32k.
794 ///
795 /// Specifying HEAP_CREATE_HARDENED prevents the heap from using locks as
796 /// pointers would potentially be exposed in heap metadata lock variables.
797 /// Callers are therefore responsible for synchronizing access to hardened heaps.
798 HARDENED: bool = false,
799 Reserved10: u2 = 0,
800 CLASS: CLASS = @enumFromInt(0),
801 /// Create heap with 16 byte alignment (obsolete)
802 ALIGN_16: bool = false,
803 /// Create heap call tracing enabled (obsolete)
804 ENABLE_TRACING: bool = false,
805 /// Create heap with executable pages
806 ///
807 /// All memory blocks that are allocated from this heap allow code execution, if the
808 /// hardware enforces data execution prevention. Use this flag heap in applications that
809 /// run code from the heap. If `ENABLE_EXECUTE` is not specified and an application
810 /// attempts to run code from a protected page, the application receives an exception
811 /// with the status code `STATUS_ACCESS_VIOLATION`.
812 ENABLE_EXECUTE: bool = false,
813 Reserved19: u13 = 0,
814
815 pub const VALID_MASK: CREATE = .{
816 .COMMON = .{
817 .NO_SERIALIZE = true,
818 .GROWABLE = true,
819 .GENERATE_EXCEPTIONS = true,
820 .ZERO_MEMORY = true,
821 .REALLOC_IN_PLACE_ONLY = true,
822 .TAIL_CHECKING_ENABLED = true,
823 .FREE_CHECKING_ENABLED = true,
824 .DISABLE_COALESCE_ON_FREE = true,
825 },
826 .CLASS = .MASK,
827 .ALIGN_16 = true,
828 .ENABLE_TRACING = true,
829 .ENABLE_EXECUTE = true,
830 .SEGMENT_HEAP = true,
831 .HARDENED = true,
832 };
833 };
834
835 pub const ALLOCATION = packed struct(ULONG) {
836 COMMON: FLAGS = .{},
837 SETTABLE_USER: packed struct(u4) {
838 VALUE: u1 = 0,
839 FLAGS: packed struct(u3) {
840 FLAG1: bool = false,
841 FLAG2: bool = false,
842 FLAG3: bool = false,
843 } = .{},
844 } = .{},
845 CLASS: CLASS = @enumFromInt(0),
846 Reserved16: u2 = 0,
847 TAG: u12 = 0,
848 Reserved30: u2 = 0,
849 };
850 };
851
852 pub const RTL_PARAMETERS = extern struct {
853 Length: ULONG,
854 SegmentReserve: SIZE_T,
855 SegmentCommit: SIZE_T,
856 DeCommitFreeBlockThreshold: SIZE_T,
857 DeCommitTotalFreeThreshold: SIZE_T,
858 MaximumAllocationSize: SIZE_T,
859 VirtualMemoryThreshold: SIZE_T,
860 InitialCommit: SIZE_T,
861 InitialReserve: SIZE_T,
862 CommitRoutine: *const COMMIT_ROUTINE,
863 Reserved: [2]SIZE_T = @splat(0),
864
865 pub const COMMIT_ROUTINE = fn (
866 Base: PVOID,
867 CommitAddress: *PVOID,
868 CommitSize: *SIZE_T,
869 ) callconv(.winapi) NTSTATUS;
870
871 pub const SEGMENT = extern struct {
872 Version: VERSION,
873 Size: USHORT,
874 Flags: FLG,
875 MemorySource: MEMORY_SOURCE,
876 Reserved: [4]SIZE_T,
877
878 pub const VERSION = enum(USHORT) {
879 CURRENT = 3,
880 _,
881 };
882
883 pub const FLG = packed struct(ULONG) {
884 USE_PAGE_HEAP: bool = false,
885 NO_LFH: bool = false,
886 Reserved2: u30 = 0,
887
888 pub const VALID_FLAGS: FLG = .{
889 .USE_PAGE_HEAP = true,
890 .NO_LFH = true,
891 };
892 };
893
894 pub const MEMORY_SOURCE = extern struct {
895 Flags: ULONG,
896 MemoryTypeMask: TYPE,
897 NumaNode: ULONG,
898 u: extern union {
899 PartitionHandle: HANDLE,
900 Callbacks: *const VA_CALLBACKS,
901 },
902 Reserved: [2]SIZE_T = @splat(0),
903
904 pub const TYPE = enum(ULONG) {
905 Paged,
906 NonPaged,
907 @"64KPage",
908 LargePage,
909 HugePage,
910 Custom,
911 _,
912
913 pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".fields.len;
914 };
915
916 pub const VA_CALLBACKS = extern struct {
917 CallbackContext: HANDLE,
918 AllocateVirtualMemory: *const ALLOCATE_VIRTUAL_MEMORY_EX_CALLBACK,
919 FreeVirtualMemory: *const FREE_VIRTUAL_MEMORY_EX_CALLBACK,
920 QueryVirtualMemory: *const QUERY_VIRTUAL_MEMORY_CALLBACK,
921
922 pub const ALLOCATE_VIRTUAL_MEMORY_EX_CALLBACK = fn (
923 CallbackContext: HANDLE,
924 BaseAddress: *PVOID,
925 RegionSize: *SIZE_T,
926 AllocationType: ULONG,
927 PageProtection: ULONG,
928 ExtendedParameters: ?[*]MEM.EXTENDED_PARAMETER,
929 ExtendedParameterCount: ULONG,
930 ) callconv(.c) NTSTATUS;
931
932 pub const FREE_VIRTUAL_MEMORY_EX_CALLBACK = fn (
933 CallbackContext: HANDLE,
934 ProcessHandle: HANDLE,
935 BaseAddress: *PVOID,
936 RegionSize: *SIZE_T,
937 FreeType: ULONG,
938 ) callconv(.c) NTSTATUS;
939
940 pub const QUERY_VIRTUAL_MEMORY_CALLBACK = fn (
941 CallbackContext: HANDLE,
942 ProcessHandle: HANDLE,
943 BaseAddress: *PVOID,
944 MemoryInformationClass: MEMORY_INFO_CLASS,
945 MemoryInformation: PVOID,
946 MemoryInformationLength: SIZE_T,
947 ReturnLength: ?*SIZE_T,
948 ) callconv(.c) NTSTATUS;
949
950 pub const MEMORY_INFO_CLASS = enum(c_int) {
951 Basic,
952 _,
953 };
954 };
955 };
956 };
957 };
958};
959
960pub const CTL_CODE = packed struct(ULONG) {
961 Method: METHOD,
962 Function: u12,
963 Access: FILE_ACCESS,
964 DeviceType: FILE_DEVICE,
965
966 pub const METHOD = enum(u2) {
967 BUFFERED = 0,
968 IN_DIRECT = 1,
969 OUT_DIRECT = 2,
970 NEITHER = 3,
971 };
972
973 pub const FILE_ACCESS = packed struct(u2) {
974 READ: bool = false,
975 WRITE: bool = false,
976
977 pub const ANY: FILE_ACCESS = .{ .READ = false, .WRITE = false };
978 pub const SPECIAL = ANY;
979 };
980
981 pub const FILE_DEVICE = enum(u16) {
982 BEEP = 0x00000001,
983 CD_ROM = 0x00000002,
984 CD_ROM_FILE_SYSTEM = 0x00000003,
985 CONTROLLER = 0x00000004,
986 DATALINK = 0x00000005,
987 DFS = 0x00000006,
988 DISK = 0x00000007,
989 DISK_FILE_SYSTEM = 0x00000008,
990 FILE_SYSTEM = 0x00000009,
991 INPORT_PORT = 0x0000000a,
992 KEYBOARD = 0x0000000b,
993 MAILSLOT = 0x0000000c,
994 MIDI_IN = 0x0000000d,
995 MIDI_OUT = 0x0000000e,
996 MOUSE = 0x0000000f,
997 MULTI_UNC_PROVIDER = 0x00000010,
998 NAMED_PIPE = 0x00000011,
999 NETWORK = 0x00000012,
1000 NETWORK_BROWSER = 0x00000013,
1001 NETWORK_FILE_SYSTEM = 0x00000014,
1002 NULL = 0x00000015,
1003 PARALLEL_PORT = 0x00000016,
1004 PHYSICAL_NETCARD = 0x00000017,
1005 PRINTER = 0x00000018,
1006 SCANNER = 0x00000019,
1007 SERIAL_MOUSE_PORT = 0x0000001a,
1008 SERIAL_PORT = 0x0000001b,
1009 SCREEN = 0x0000001c,
1010 SOUND = 0x0000001d,
1011 STREAMS = 0x0000001e,
1012 TAPE = 0x0000001f,
1013 TAPE_FILE_SYSTEM = 0x00000020,
1014 TRANSPORT = 0x00000021,
1015 UNKNOWN = 0x00000022,
1016 VIDEO = 0x00000023,
1017 VIRTUAL_DISK = 0x00000024,
1018 WAVE_IN = 0x00000025,
1019 WAVE_OUT = 0x00000026,
1020 @"8042_PORT" = 0x00000027,
1021 NETWORK_REDIRECTOR = 0x00000028,
1022 BATTERY = 0x00000029,
1023 BUS_EXTENDER = 0x0000002a,
1024 MODEM = 0x0000002b,
1025 VDM = 0x0000002c,
1026 MASS_STORAGE = 0x0000002d,
1027 SMB = 0x0000002e,
1028 KS = 0x0000002f,
1029 CHANGER = 0x00000030,
1030 SMARTCARD = 0x00000031,
1031 ACPI = 0x00000032,
1032 DVD = 0x00000033,
1033 FULLSCREEN_VIDEO = 0x00000034,
1034 DFS_FILE_SYSTEM = 0x00000035,
1035 DFS_VOLUME = 0x00000036,
1036 SERENUM = 0x00000037,
1037 TERMSRV = 0x00000038,
1038 KSEC = 0x00000039,
1039 FIPS = 0x0000003A,
1040 INFINIBAND = 0x0000003B,
1041 VMBUS = 0x0000003E,
1042 CRYPT_PROVIDER = 0x0000003F,
1043 WPD = 0x00000040,
1044 BLUETOOTH = 0x00000041,
1045 MT_COMPOSITE = 0x00000042,
1046 MT_TRANSPORT = 0x00000043,
1047 BIOMETRIC = 0x00000044,
1048 PMI = 0x00000045,
1049 EHSTOR = 0x00000046,
1050 DEVAPI = 0x00000047,
1051 GPIO = 0x00000048,
1052 USBEX = 0x00000049,
1053 CONSOLE = 0x00000050,
1054 NFP = 0x00000051,
1055 SYSENV = 0x00000052,
1056 VIRTUAL_BLOCK = 0x00000053,
1057 POINT_OF_SERVICE = 0x00000054,
1058 STORAGE_REPLICATION = 0x00000055,
1059 TRUST_ENV = 0x00000056,
1060 UCM = 0x00000057,
1061 UCMTCPCI = 0x00000058,
1062 PERSISTENT_MEMORY = 0x00000059,
1063 NVDIMM = 0x0000005a,
1064 HOLOGRAPHIC = 0x0000005b,
1065 SDFXHCI = 0x0000005c,
1066 UCMUCSI = 0x0000005d,
1067 PRM = 0x0000005e,
1068 EVENT_COLLECTOR = 0x0000005f,
1069 USB4 = 0x00000060,
1070 SOUNDWIRE = 0x00000061,
1071
1072 MOUNTMGRCONTROLTYPE = 'm',
1073
1074 _,
1075 };
1076};
1077
1078pub const IOCTL = struct {
1079 pub const MOUNTMGR = struct {
1080 pub const QUERY_POINTS: CTL_CODE = .{ .DeviceType = .MOUNTMGRCONTROLTYPE, .Function = 2, .Method = .BUFFERED, .Access = .ANY };
1081 pub const QUERY_DOS_VOLUME_PATH: CTL_CODE = .{ .DeviceType = .MOUNTMGRCONTROLTYPE, .Function = 12, .Method = .BUFFERED, .Access = .ANY };
1082 };
1083};
1084
1085pub const FSCTL = struct {
1086 pub const SET_REPARSE_POINT: CTL_CODE = .{ .DeviceType = .FILE_SYSTEM, .Function = 41, .Method = .BUFFERED, .Access = .SPECIAL };
1087 pub const GET_REPARSE_POINT: CTL_CODE = .{ .DeviceType = .FILE_SYSTEM, .Function = 42, .Method = .BUFFERED, .Access = .ANY };
1088
1089 pub const PIPE = struct {
1090 pub const ASSIGN_EVENT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 0, .Method = .BUFFERED, .Access = .ANY };
1091 pub const DISCONNECT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 1, .Method = .BUFFERED, .Access = .ANY };
1092 pub const LISTEN: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2, .Method = .BUFFERED, .Access = .ANY };
1093 pub const PEEK: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 3, .Method = .BUFFERED, .Access = .{ .READ = true } };
1094 pub const QUERY_EVENT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 4, .Method = .BUFFERED, .Access = .ANY };
1095 pub const TRANSCEIVE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 5, .Method = .NEITHER, .Access = .{ .READ = true, .WRITE = true } };
1096 pub const WAIT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 6, .Method = .BUFFERED, .Access = .ANY };
1097 pub const IMPERSONATE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 7, .Method = .BUFFERED, .Access = .ANY };
1098 pub const SET_CLIENT_PROCESS: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 8, .Method = .BUFFERED, .Access = .ANY };
1099 pub const QUERY_CLIENT_PROCESS: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 9, .Method = .BUFFERED, .Access = .ANY };
1100 pub const GET_PIPE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 10, .Method = .BUFFERED, .Access = .ANY };
1101 pub const SET_PIPE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 11, .Method = .BUFFERED, .Access = .ANY };
1102 pub const GET_CONNECTION_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 12, .Method = .BUFFERED, .Access = .ANY };
1103 pub const SET_CONNECTION_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 13, .Method = .BUFFERED, .Access = .ANY };
1104 pub const GET_HANDLE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 14, .Method = .BUFFERED, .Access = .ANY };
1105 pub const SET_HANDLE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 15, .Method = .BUFFERED, .Access = .ANY };
1106 pub const FLUSH: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 16, .Method = .BUFFERED, .Access = .{ .WRITE = true } };
1107
1108 pub const INTERNAL_READ: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2045, .Method = .BUFFERED, .Access = .{ .READ = true } };
1109 pub const INTERNAL_WRITE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2046, .Method = .BUFFERED, .Access = .{ .WRITE = true } };
1110 pub const INTERNAL_TRANSCEIVE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2047, .Method = .NEITHER, .Access = .{ .READ = true, .WRITE = true } };
1111 pub const INTERNAL_READ_OVFLOW: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2048, .Method = .BUFFERED, .Access = .{ .READ = true } };
1112 };
1113};
1114
1115pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: ULONG = 16 * 1024;
1116
1117pub const IO_REPARSE_TAG = packed struct(ULONG) {
1118 Value: u12,
1119 Index: u4 = 0,
1120 ReservedBits: u12 = 0,
1121 /// Can have children if a directory.
1122 IsDirectory: bool = false,
1123 /// Represents another named entity in the system.
1124 IsSurrogate: bool = false,
1125 /// Must be `false` for non-Microsoft tags.
1126 IsReserved: bool = false,
1127 /// Owned by Microsoft.
1128 IsMicrosoft: bool = false,
1129
1130 pub const RESERVED_INVALID: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsReserved = true, .Index = 0x8, .Value = 0x000 };
1131 pub const MOUNT_POINT: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x003 };
1132 pub const HSM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsReserved = true, .Value = 0x004 };
1133 pub const DRIVE_EXTENDER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x005 };
1134 pub const HSM2: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x006 };
1135 pub const SIS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x007 };
1136 pub const WIM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x008 };
1137 pub const CSV: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x009 };
1138 pub const DFS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x00A };
1139 pub const FILTER_MANAGER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x00B };
1140 pub const SYMLINK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x00C };
1141 pub const IIS_CACHE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x010 };
1142 pub const DFSR: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x012 };
1143 pub const DEDUP: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x013 };
1144 pub const APPXSTRM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsReserved = true, .Value = 0x014 };
1145 pub const NFS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x014 };
1146 pub const FILE_PLACEHOLDER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x015 };
1147 pub const DFM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x016 };
1148 pub const WOF: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x017 };
1149 pub inline fn WCI(index: u1) IO_REPARSE_TAG {
1150 return .{ .IsMicrosoft = true, .IsDirectory = index == 0x1, .Index = index, .Value = 0x018 };
1151 }
1152 pub const GLOBAL_REPARSE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x0019 };
1153 pub inline fn CLOUD(index: u4) IO_REPARSE_TAG {
1154 return .{ .IsMicrosoft = true, .IsDirectory = true, .Index = index, .Value = 0x01A };
1155 }
1156 pub const APPEXECLINK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x01B };
1157 pub const PROJFS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsDirectory = true, .Value = 0x01C };
1158 pub const LX_SYMLINK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x01D };
1159 pub const STORAGE_SYNC: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x01E };
1160 pub const WCI_TOMBSTONE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x01F };
1161 pub const UNHANDLED: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x020 };
1162 pub const ONEDRIVE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x021 };
1163 pub const PROJFS_TOMBSTONE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x022 };
1164 pub const AF_UNIX: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x023 };
1165 pub const LX_FIFO: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x024 };
1166 pub const LX_CHR: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x025 };
1167 pub const LX_BLK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x026 };
1168 pub const LX_STORAGE_SYNC_FOLDER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsDirectory = true, .Value = 0x027 };
1169 pub inline fn WCI_LINK(index: u1) IO_REPARSE_TAG {
1170 return .{ .IsMicrosoft = true, .IsSurrogate = true, .Index = index, .Value = 0x027 };
1171 }
1172 pub const DATALESS_CIM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x28 };
1173};
1174
1175// ref: km/wdm.h
1176
1177pub const ACCESS_MASK = packed struct(DWORD) {
1178 SPECIFIC: Specific = .{ .bits = 0 },
1179 STANDARD: Standard = .{},
1180 Reserved21: u3 = 0,
1181 ACCESS_SYSTEM_SECURITY: bool = false,
1182 MAXIMUM_ALLOWED: bool = false,
1183 Reserved26: u2 = 0,
1184 GENERIC: Generic = .{},
1185
1186 pub const Specific = packed union {
1187 bits: u16,
1188
1189 // ref: km/wdm.h
1190
1191 /// Define access rights to files and directories
1192 FILE: File,
1193 FILE_DIRECTORY: File.Directory,
1194 FILE_PIPE: File.Pipe,
1195 /// Registry Specific Access Rights.
1196 KEY: Key,
1197 /// Object Manager Object Type Specific Access Rights.
1198 OBJECT_TYPE: ObjectType,
1199 /// Object Manager Directory Specific Access Rights.
1200 DIRECTORY: Directory,
1201 /// Object Manager Symbolic Link Specific Access Rights.
1202 SYMBOLIC_LINK: SymbolicLink,
1203 /// Section Access Rights.
1204 SECTION: Section,
1205 /// Session Specific Access Rights.
1206 SESSION: Session,
1207 /// Process Specific Access Rights.
1208 PROCESS: Process,
1209 /// Thread Specific Access Rights.
1210 THREAD: Thread,
1211 /// Partition Specific Access Rights.
1212 MEMORY_PARTITION: MemoryPartition,
1213 /// Generic mappings for transaction manager rights.
1214 TRANSACTIONMANAGER: TransactionManager,
1215 /// Generic mappings for transaction rights.
1216 TRANSACTION: Transaction,
1217 /// Generic mappings for resource manager rights.
1218 RESOURCEMANAGER: ResourceManager,
1219 /// Generic mappings for enlistment rights.
1220 ENLISTMENT: Enlistment,
1221 /// Event Specific Access Rights.
1222 EVENT: Event,
1223 /// Semaphore Specific Access Rights.
1224 SEMAPHORE: Semaphore,
1225
1226 // ref: km/ntifs.h
1227
1228 /// Token Specific Access Rights.
1229 TOKEN: Token,
1230
1231 // um/winnt.h
1232
1233 /// Job Object Specific Access Rights.
1234 JOB_OBJECT: JobObject,
1235 /// Mutant Specific Access Rights.
1236 MUTANT: Mutant,
1237 /// Timer Specific Access Rights.
1238 TIMER: Timer,
1239 /// I/O Completion Specific Access Rights.
1240 IO_COMPLETION: IoCompletion,
1241
1242 pub const File = packed struct(u16) {
1243 READ_DATA: bool = false,
1244 WRITE_DATA: bool = false,
1245 APPEND_DATA: bool = false,
1246 READ_EA: bool = false,
1247 WRITE_EA: bool = false,
1248 EXECUTE: bool = false,
1249 Reserved6: u1 = 0,
1250 READ_ATTRIBUTES: bool = false,
1251 WRITE_ATTRIBUTES: bool = false,
1252 Reserved9: u7 = 0,
1253
1254 pub const ALL_ACCESS: ACCESS_MASK = .{
1255 .STANDARD = .{
1256 .RIGHTS = .REQUIRED,
1257 .SYNCHRONIZE = true,
1258 },
1259 .SPECIFIC = .{ .FILE = .{
1260 .READ_DATA = true,
1261 .WRITE_DATA = true,
1262 .APPEND_DATA = true,
1263 .READ_EA = true,
1264 .WRITE_EA = true,
1265 .EXECUTE = true,
1266 .Reserved6 = maxInt(@FieldType(File, "Reserved6")),
1267 .READ_ATTRIBUTES = true,
1268 .WRITE_ATTRIBUTES = true,
1269 } },
1270 };
1271
1272 pub const GENERIC_READ: ACCESS_MASK = .{
1273 .STANDARD = .{
1274 .RIGHTS = .READ,
1275 .SYNCHRONIZE = true,
1276 },
1277 .SPECIFIC = .{ .FILE = .{
1278 .READ_DATA = true,
1279 .READ_ATTRIBUTES = true,
1280 .READ_EA = true,
1281 } },
1282 };
1283
1284 pub const GENERIC_WRITE: ACCESS_MASK = .{
1285 .STANDARD = .{
1286 .RIGHTS = .WRITE,
1287 .SYNCHRONIZE = true,
1288 },
1289 .SPECIFIC = .{ .FILE = .{
1290 .WRITE_DATA = true,
1291 .WRITE_ATTRIBUTES = true,
1292 .WRITE_EA = true,
1293 .APPEND_DATA = true,
1294 } },
1295 };
1296
1297 pub const GENERIC_EXECUTE: ACCESS_MASK = .{
1298 .STANDARD = .{
1299 .RIGHTS = .EXECUTE,
1300 .SYNCHRONIZE = true,
1301 },
1302 .SPECIFIC = .{ .FILE = .{
1303 .READ_ATTRIBUTES = true,
1304 .EXECUTE = true,
1305 } },
1306 };
1307
1308 pub const Directory = packed struct(u16) {
1309 LIST: bool = false,
1310 ADD_FILE: bool = false,
1311 ADD_SUBDIRECTORY: bool = false,
1312 READ_EA: bool = false,
1313 WRITE_EA: bool = false,
1314 TRAVERSE: bool = false,
1315 DELETE_CHILD: bool = false,
1316 READ_ATTRIBUTES: bool = false,
1317 WRITE_ATTRIBUTES: bool = false,
1318 Reserved9: u7 = 0,
1319 };
1320
1321 pub const Pipe = packed struct(u16) {
1322 READ_DATA: bool = false,
1323 WRITE_DATA: bool = false,
1324 CREATE_PIPE_INSTANCE: bool = false,
1325 Reserved3: u4 = 0,
1326 READ_ATTRIBUTES: bool = false,
1327 WRITE_ATTRIBUTES: bool = false,
1328 Reserved9: u7 = 0,
1329 };
1330 };
1331
1332 pub const Key = packed struct(u16) {
1333 /// Required to query the values of a registry key.
1334 QUERY_VALUE: bool = false,
1335 /// Required to create, delete, or set a registry value.
1336 SET_VALUE: bool = false,
1337 /// Required to create a subkey of a registry key.
1338 CREATE_SUB_KEY: bool = false,
1339 /// Required to enumerate the subkeys of a registry key.
1340 ENUMERATE_SUB_KEYS: bool = false,
1341 /// Required to request change notifications for a registry key or for subkeys of a registry key.
1342 NOTIFY: bool = false,
1343 /// Reserved for system use.
1344 CREATE_LINK: bool = false,
1345 Reserved6: u2 = 0,
1346 /// Indicates that an application on 64-bit Windows should operate on the 64-bit registry view.
1347 /// This flag is ignored by 32-bit Windows.
1348 WOW64_64KEY: bool = false,
1349 /// Indicates that an application on 64-bit Windows should operate on the 32-bit registry view.
1350 /// This flag is ignored by 32-bit Windows.
1351 WOW64_32KEY: bool = false,
1352 Reserved10: u6 = 0,
1353
1354 pub const WOW64_RES: ACCESS_MASK = .{
1355 .SPECIFIC = .{ .KEY = .{
1356 .WOW64_32KEY = true,
1357 .WOW64_64KEY = true,
1358 } },
1359 };
1360
1361 /// Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values.
1362 pub const READ: ACCESS_MASK = .{
1363 .STANDARD = .{
1364 .RIGHTS = .READ,
1365 .SYNCHRONIZE = false,
1366 },
1367 .SPECIFIC = .{ .KEY = .{
1368 .QUERY_VALUE = true,
1369 .ENUMERATE_SUB_KEYS = true,
1370 .NOTIFY = true,
1371 } },
1372 };
1373
1374 /// Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY access rights.
1375 pub const WRITE: ACCESS_MASK = .{
1376 .STANDARD = .{
1377 .RIGHTS = .WRITE,
1378 .SYNCHRONIZE = false,
1379 },
1380 .SPECIFIC = .{ .KEY = .{
1381 .SET_VALUE = true,
1382 .CREATE_SUB_KEY = true,
1383 } },
1384 };
1385
1386 /// Equivalent to KEY_READ.
1387 pub const EXECUTE = READ;
1388
1389 pub const ALL_ACCESS: ACCESS_MASK = .{
1390 .STANDARD = .{
1391 .RIGHTS = .ALL,
1392 .SYNCHRONIZE = false,
1393 },
1394 .SPECIFIC = .{ .KEY = .{
1395 .QUERY_VALUE = true,
1396 .SET_VALUE = true,
1397 .CREATE_SUB_KEY = true,
1398 .ENUMERATE_SUB_KEYS = true,
1399 .NOTIFY = true,
1400 .CREATE_LINK = true,
1401 } },
1402 };
1403 };
1404
1405 pub const ObjectType = packed struct(u16) {
1406 CREATE: bool = false,
1407 Reserved1: u15 = 0,
1408
1409 pub const ALL_ACCESS: ACCESS_MASK = .{
1410 .STANDARD = .{ .RIGHTS = .REQUIRED },
1411 .SPECIFIC = .{ .OBJECT_TYPE = .{
1412 .CREATE = true,
1413 } },
1414 };
1415 };
1416
1417 pub const Directory = packed struct(u16) {
1418 QUERY: bool = false,
1419 TRAVERSE: bool = false,
1420 CREATE_OBJECT: bool = false,
1421 CREATE_SUBDIRECTORY: bool = false,
1422 Reserved3: u12 = 0,
1423
1424 pub const ALL_ACCESS: ACCESS_MASK = .{
1425 .STANDARD = .{ .RIGHTS = .REQUIRED },
1426 .SPECIFIC = .{ .DIRECTORY = .{
1427 .QUERY = true,
1428 .TRAVERSE = true,
1429 .CREATE_OBJECT = true,
1430 .CREATE_SUBDIRECTORY = true,
1431 } },
1432 };
1433 };
1434
1435 pub const SymbolicLink = packed struct(u16) {
1436 QUERY: bool = false,
1437 SET: bool = false,
1438 Reserved2: u14 = 0,
1439
1440 pub const ALL_ACCESS: ACCESS_MASK = .{
1441 .STANDARD = .{ .RIGHTS = .REQUIRED },
1442 .SPECIFIC = .{ .SYMBOLIC_LINK = .{
1443 .QUERY = true,
1444 } },
1445 };
1446
1447 pub const ALL_ACCESS_EX: ACCESS_MASK = .{
1448 .STANDARD = .{ .RIGHTS = .REQUIRED },
1449 .SPECIFIC = .{ .SYMBOLIC_LINK = .{
1450 .QUERY = true,
1451 .SET = true,
1452 .Reserved2 = maxInt(@FieldType(SymbolicLink, "Reserved2")),
1453 } },
1454 };
1455 };
1456
1457 pub const Section = packed struct(u16) {
1458 QUERY: bool = false,
1459 MAP_WRITE: bool = false,
1460 MAP_READ: bool = false,
1461 MAP_EXECUTE: bool = false,
1462 EXTEND_SIZE: bool = false,
1463 /// not included in `ALL_ACCESS`
1464 MAP_EXECUTE_EXPLICIT: bool = false,
1465 Reserved6: u10 = 0,
1466
1467 pub const ALL_ACCESS: ACCESS_MASK = .{
1468 .STANDARD = .{ .RIGHTS = .REQUIRED },
1469 .SPECIFIC = .{ .SECTION = .{
1470 .QUERY = true,
1471 .MAP_WRITE = true,
1472 .MAP_READ = true,
1473 .MAP_EXECUTE = true,
1474 .EXTEND_SIZE = true,
1475 } },
1476 };
1477 };
1478
1479 pub const Session = packed struct(u16) {
1480 QUERY_ACCESS: bool = false,
1481 MODIFY_ACCESS: bool = false,
1482 Reserved2: u14 = 0,
1483
1484 pub const ALL_ACCESS: ACCESS_MASK = .{
1485 .STANDARD = .{ .RIGHTS = .REQUIRED },
1486 .SPECIFIC = .{ .SESSION = .{
1487 .QUERY_ACCESS = true,
1488 .MODIFY_ACCESS = true,
1489 } },
1490 };
1491 };
1492
1493 pub const Process = packed struct(u16) {
1494 TERMINATE: bool = false,
1495 CREATE_THREAD: bool = false,
1496 SET_SESSIONID: bool = false,
1497 VM_OPERATION: bool = false,
1498 VM_READ: bool = false,
1499 VM_WRITE: bool = false,
1500 DUP_HANDLE: bool = false,
1501 CREATE_PROCESS: bool = false,
1502 SET_QUOTA: bool = false,
1503 SET_INFORMATION: bool = false,
1504 QUERY_INFORMATION: bool = false,
1505 SUSPEND_RESUME: bool = false,
1506 QUERY_LIMITED_INFORMATION: bool = false,
1507 SET_LIMITED_INFORMATION: bool = false,
1508 Reserved14: u2 = 0,
1509
1510 pub const ALL_ACCESS: ACCESS_MASK = .{
1511 .STANDARD = .{
1512 .RIGHTS = .REQUIRED,
1513 .SYNCHRONIZE = true,
1514 },
1515 .SPECIFIC = .{ .PROCESS = .{
1516 .TERMINATE = true,
1517 .CREATE_THREAD = true,
1518 .SET_SESSIONID = true,
1519 .VM_OPERATION = true,
1520 .VM_READ = true,
1521 .VM_WRITE = true,
1522 .DUP_HANDLE = true,
1523 .CREATE_PROCESS = true,
1524 .SET_QUOTA = true,
1525 .SET_INFORMATION = true,
1526 .QUERY_INFORMATION = true,
1527 .SUSPEND_RESUME = true,
1528 .QUERY_LIMITED_INFORMATION = true,
1529 .SET_LIMITED_INFORMATION = true,
1530 .Reserved14 = maxInt(@FieldType(Process, "Reserved14")),
1531 } },
1532 };
1533 };
1534
1535 pub const Thread = packed struct(u16) {
1536 TERMINATE: bool = false,
1537 SUSPEND_RESUME: bool = false,
1538 ALERT: bool = false,
1539 GET_CONTEXT: bool = false,
1540 SET_CONTEXT: bool = false,
1541 SET_INFORMATION: bool = false,
1542 QUERY_INFORMATION: bool = false,
1543 SET_THREAD_TOKEN: bool = false,
1544 IMPERSONATE: bool = false,
1545 DIRECT_IMPERSONATION: bool = false,
1546 SET_LIMITED_INFORMATION: bool = false,
1547 QUERY_LIMITED_INFORMATION: bool = false,
1548 RESUME: bool = false,
1549 Reserved13: u3 = 0,
1550
1551 pub const ALL_ACCESS: ACCESS_MASK = .{
1552 .STANDARD = .{
1553 .RIGHTS = .REQUIRED,
1554 .SYNCHRONIZE = true,
1555 },
1556 .SPECIFIC = .{ .THREAD = .{
1557 .TERMINATE = true,
1558 .SUSPEND_RESUME = true,
1559 .ALERT = true,
1560 .GET_CONTEXT = true,
1561 .SET_CONTEXT = true,
1562 .SET_INFORMATION = true,
1563 .QUERY_INFORMATION = true,
1564 .SET_THREAD_TOKEN = true,
1565 .IMPERSONATE = true,
1566 .DIRECT_IMPERSONATION = true,
1567 .SET_LIMITED_INFORMATION = true,
1568 .QUERY_LIMITED_INFORMATION = true,
1569 .RESUME = true,
1570 .Reserved13 = maxInt(@FieldType(Thread, "Reserved13")),
1571 } },
1572 };
1573 };
1574
1575 pub const MemoryPartition = packed struct(u16) {
1576 QUERY_ACCESS: bool = false,
1577 MODIFY_ACCESS: bool = false,
1578 Required2: u14 = 0,
1579
1580 pub const ALL_ACCESS: ACCESS_MASK = .{
1581 .STANDARD = .{
1582 .RIGHTS = .REQUIRED,
1583 .SYNCHRONIZE = true,
1584 },
1585 .SPECIFIC = .{ .MEMORY_PARTITION = .{
1586 .QUERY_ACCESS = true,
1587 .MODIFY_ACCESS = true,
1588 } },
1589 };
1590 };
1591
1592 pub const TransactionManager = packed struct(u16) {
1593 QUERY_INFORMATION: bool = false,
1594 SET_INFORMATION: bool = false,
1595 RECOVER: bool = false,
1596 RENAME: bool = false,
1597 CREATE_RM: bool = false,
1598 /// The following right is intended for DTC's use only; it will be deprecated, and no one else should take a dependency on it.
1599 BIND_TRANSACTION: bool = false,
1600 Reserved6: u10 = 0,
1601
1602 pub const GENERIC_READ: ACCESS_MASK = .{
1603 .STANDARD = .{ .RIGHTS = .READ },
1604 .SPECIFIC = .{ .TRANSACTIONMANAGER = .{
1605 .QUERY_INFORMATION = true,
1606 } },
1607 };
1608
1609 pub const GENERIC_WRITE: ACCESS_MASK = .{
1610 .STANDARD = .{ .RIGHTS = .WRITE },
1611 .SPECIFIC = .{ .TRANSACTIONMANAGER = .{
1612 .SET_INFORMATION = true,
1613 .RECOVER = true,
1614 .RENAME = true,
1615 .CREATE_RM = true,
1616 } },
1617 };
1618
1619 pub const GENERIC_EXECUTE: ACCESS_MASK = .{
1620 .STANDARD = .{ .RIGHTS = .EXECUTE },
1621 .SPECIFIC = .{ .TRANSACTIONMANAGER = .{} },
1622 };
1623
1624 pub const ALL_ACCESS: ACCESS_MASK = .{
1625 .STANDARD = .{ .RIGHTS = .REQUIRED },
1626 .SPECIFIC = .{ .TRANSACTIONMANAGER = .{
1627 .QUERY_INFORMATION = true,
1628 .SET_INFORMATION = true,
1629 .RECOVER = true,
1630 .RENAME = true,
1631 .CREATE_RM = true,
1632 .BIND_TRANSACTION = true,
1633 } },
1634 };
1635 };
1636
1637 pub const Transaction = packed struct(u16) {
1638 QUERY_INFORMATION: bool = false,
1639 SET_INFORMATION: bool = false,
1640 ENLIST: bool = false,
1641 COMMIT: bool = false,
1642 ROLLBACK: bool = false,
1643 PROPAGATE: bool = false,
1644 RIGHT_RESERVED1: bool = false,
1645 Reserved7: u9 = 0,
1646
1647 pub const GENERIC_READ: ACCESS_MASK = .{
1648 .STANDARD = .{
1649 .RIGHTS = .READ,
1650 .SYNCHRONIZE = true,
1651 },
1652 .SPECIFIC = .{ .TRANSACTION = .{
1653 .QUERY_INFORMATION = true,
1654 } },
1655 };
1656
1657 pub const GENERIC_WRITE: ACCESS_MASK = .{
1658 .STANDARD = .{
1659 .RIGHTS = .WRITE,
1660 .SYNCHRONIZE = true,
1661 },
1662 .SPECIFIC = .{ .TRANSACTION = .{
1663 .SET_INFORMATION = true,
1664 .COMMIT = true,
1665 .ENLIST = true,
1666 .ROLLBACK = true,
1667 .PROPAGATE = true,
1668 } },
1669 };
1670
1671 pub const GENERIC_EXECUTE: ACCESS_MASK = .{
1672 .STANDARD = .{
1673 .RIGHTS = .EXECUTE,
1674 .SYNCHRONIZE = true,
1675 },
1676 .SPECIFIC = .{ .TRANSACTION = .{
1677 .COMMIT = true,
1678 .ROLLBACK = true,
1679 } },
1680 };
1681
1682 pub const ALL_ACCESS: ACCESS_MASK = .{
1683 .STANDARD = .{
1684 .RIGHTS = .REQUIRED,
1685 .SYNCHRONIZE = true,
1686 },
1687 .SPECIFIC = .{ .TRANSACTION = .{
1688 .QUERY_INFORMATION = true,
1689 .SET_INFORMATION = true,
1690 .COMMIT = true,
1691 .ENLIST = true,
1692 .ROLLBACK = true,
1693 .PROPAGATE = true,
1694 } },
1695 };
1696
1697 pub const RESOURCE_MANAGER_RIGHTS: ACCESS_MASK = .{
1698 .STANDARD = .{
1699 .RIGHTS = .{
1700 .READ_CONTROL = true,
1701 },
1702 .SYNCHRONIZE = true,
1703 },
1704 .SPECIFIC = .{ .TRANSACTION = .{
1705 .QUERY_INFORMATION = true,
1706 .SET_INFORMATION = true,
1707 .ENLIST = true,
1708 .ROLLBACK = true,
1709 .PROPAGATE = true,
1710 } },
1711 };
1712 };
1713
1714 pub const ResourceManager = packed struct(u16) {
1715 QUERY_INFORMATION: bool = false,
1716 SET_INFORMATION: bool = false,
1717 RECOVER: bool = false,
1718 ENLIST: bool = false,
1719 GET_NOTIFICATION: bool = false,
1720 REGISTER_PROTOCOL: bool = false,
1721 COMPLETE_PROPAGATION: bool = false,
1722 Reserved7: u9 = 0,
1723
1724 pub const GENERIC_READ: ACCESS_MASK = .{
1725 .STANDARD = .{
1726 .RIGHTS = .READ,
1727 .SYNCHRONIZE = true,
1728 },
1729 .SPECIFIC = .{ .RESOURCEMANAGER = .{
1730 .QUERY_INFORMATION = true,
1731 } },
1732 };
1733
1734 pub const GENERIC_WRITE: ACCESS_MASK = .{
1735 .STANDARD = .{
1736 .RIGHTS = .WRITE,
1737 .SYNCHRONIZE = true,
1738 },
1739 .SPECIFIC = .{ .RESOURCEMANAGER = .{
1740 .SET_INFORMATION = true,
1741 .RECOVER = true,
1742 .ENLIST = true,
1743 .GET_NOTIFICATION = true,
1744 .REGISTER_PROTOCOL = true,
1745 .COMPLETE_PROPAGATION = true,
1746 } },
1747 };
1748
1749 pub const GENERIC_EXECUTE: ACCESS_MASK = .{
1750 .STANDARD = .{
1751 .RIGHTS = .EXECUTE,
1752 .SYNCHRONIZE = true,
1753 },
1754 .SPECIFIC = .{ .RESOURCEMANAGER = .{
1755 .RECOVER = true,
1756 .ENLIST = true,
1757 .GET_NOTIFICATION = true,
1758 .COMPLETE_PROPAGATION = true,
1759 } },
1760 };
1761
1762 pub const ALL_ACCESS: ACCESS_MASK = .{
1763 .STANDARD = .{
1764 .RIGHTS = .REQUIRED,
1765 .SYNCHRONIZE = true,
1766 },
1767 .SPECIFIC = .{ .RESOURCEMANAGER = .{
1768 .QUERY_INFORMATION = true,
1769 .SET_INFORMATION = true,
1770 .RECOVER = true,
1771 .ENLIST = true,
1772 .GET_NOTIFICATION = true,
1773 .REGISTER_PROTOCOL = true,
1774 .COMPLETE_PROPAGATION = true,
1775 } },
1776 };
1777 };
1778
1779 pub const Enlistment = packed struct(u16) {
1780 QUERY_INFORMATION: bool = false,
1781 SET_INFORMATION: bool = false,
1782 RECOVER: bool = false,
1783 SUBORDINATE_RIGHTS: bool = false,
1784 SUPERIOR_RIGHTS: bool = false,
1785 Reserved5: u11 = 0,
1786
1787 pub const GENERIC_READ: ACCESS_MASK = .{
1788 .STANDARD = .{ .RIGHTS = .READ },
1789 .SPECIFIC = .{ .ENLISTMENT = .{
1790 .QUERY_INFORMATION = true,
1791 } },
1792 };
1793
1794 pub const GENERIC_WRITE: ACCESS_MASK = .{
1795 .STANDARD = .{ .RIGHTS = .WRITE },
1796 .SPECIFIC = .{ .ENLISTMENT = .{
1797 .SET_INFORMATION = true,
1798 .RECOVER = true,
1799 .SUBORDINATE_RIGHTS = true,
1800 .SUPERIOR_RIGHTS = true,
1801 } },
1802 };
1803
1804 pub const GENERIC_EXECUTE: ACCESS_MASK = .{
1805 .STANDARD = .{ .RIGHTS = .EXECUTE },
1806 .SPECIFIC = .{ .ENLISTMENT = .{
1807 .RECOVER = true,
1808 .SUBORDINATE_RIGHTS = true,
1809 .SUPERIOR_RIGHTS = true,
1810 } },
1811 };
1812
1813 pub const ALL_ACCESS: ACCESS_MASK = .{
1814 .STANDARD = .{ .RIGHTS = .REQUIRED },
1815 .SPECIFIC = .{ .ENLISTMENT = .{
1816 .QUERY_INFORMATION = true,
1817 .SET_INFORMATION = true,
1818 .RECOVER = true,
1819 .SUBORDINATE_RIGHTS = true,
1820 .SUPERIOR_RIGHTS = true,
1821 } },
1822 };
1823 };
1824
1825 pub const Event = packed struct(u16) {
1826 QUERY_STATE: bool = false,
1827 MODIFY_STATE: bool = false,
1828 Reserved2: u14 = 0,
1829
1830 pub const ALL_ACCESS: ACCESS_MASK = .{
1831 .STANDARD = .{
1832 .RIGHTS = .REQUIRED,
1833 .SYNCHRONIZE = true,
1834 },
1835 .SPECIFIC = .{ .EVENT = .{
1836 .QUERY_STATE = true,
1837 .MODIFY_STATE = true,
1838 } },
1839 };
1840 };
1841
1842 pub const Semaphore = packed struct(u16) {
1843 QUERY_STATE: bool = false,
1844 MODIFY_STATE: bool = false,
1845 Reserved2: u14 = 0,
1846
1847 pub const ALL_ACCESS: ACCESS_MASK = .{
1848 .STANDARD = .{
1849 .RIGHTS = .REQUIRED,
1850 .SYNCHRONIZE = true,
1851 },
1852 .SPECIFIC = .{ .SEMAPHORE = .{
1853 .QUERY_STATE = true,
1854 .MODIFY_STATE = true,
1855 } },
1856 };
1857 };
1858
1859 pub const Token = packed struct(u16) {
1860 ASSIGN_PRIMARY: bool = false,
1861 DUPLICATE: bool = false,
1862 IMPERSONATE: bool = false,
1863 QUERY: bool = false,
1864 QUERY_SOURCE: bool = false,
1865 ADJUST_PRIVILEGES: bool = false,
1866 ADJUST_GROUPS: bool = false,
1867 ADJUST_DEFAULT: bool = false,
1868 ADJUST_SESSIONID: bool = false,
1869 Reserved9: u7 = 0,
1870
1871 pub const ALL_ACCESS_P: ACCESS_MASK = .{
1872 .STANDARD = .{ .RIGHTS = .REQUIRED },
1873 .SPECIFIC = .{ .TOKEN = .{
1874 .ASSIGN_PRIMARY = true,
1875 .DUPLICATE = true,
1876 .IMPERSONATE = true,
1877 .QUERY = true,
1878 .QUERY_SOURCE = true,
1879 .ADJUST_PRIVILEGES = true,
1880 .ADJUST_GROUPS = true,
1881 .ADJUST_DEFAULT = true,
1882 } },
1883 };
1884
1885 pub const ALL_ACCESS: ACCESS_MASK = .{
1886 .STANDARD = .{ .RIGHTS = .REQUIRED },
1887 .SPECIFIC = .{ .TOKEN = .{
1888 .ASSIGN_PRIMARY = true,
1889 .DUPLICATE = true,
1890 .IMPERSONATE = true,
1891 .QUERY = true,
1892 .QUERY_SOURCE = true,
1893 .ADJUST_PRIVILEGES = true,
1894 .ADJUST_GROUPS = true,
1895 .ADJUST_DEFAULT = true,
1896 .ADJUST_SESSIONID = true,
1897 } },
1898 };
1899
1900 pub const READ: ACCESS_MASK = .{
1901 .STANDARD = .{ .RIGHTS = .READ },
1902 .SPECIFIC = .{ .TOKEN = .{
1903 .QUERY = true,
1904 } },
1905 };
1906
1907 pub const WRITE: ACCESS_MASK = .{
1908 .STANDARD = .{ .RIGHTS = .WRITE },
1909 .SPECIFIC = .{ .TOKEN = .{
1910 .ADJUST_PRIVILEGES = true,
1911 .ADJUST_GROUPS = true,
1912 .ADJUST_DEFAULT = true,
1913 } },
1914 };
1915
1916 pub const EXECUTE: ACCESS_MASK = .{
1917 .STANDARD = .{ .RIGHTS = .EXECUTE },
1918 .SPECIFIC = .{ .TOKEN = .{} },
1919 };
1920
1921 pub const TRUST_CONSTRAINT_MASK: ACCESS_MASK = .{
1922 .STANDARD = .{ .RIGHTS = .READ },
1923 .SPECIFIC = .{ .TOKEN = .{
1924 .QUERY = true,
1925 .QUERY_SOURCE = true,
1926 } },
1927 };
1928
1929 pub const TRUST_ALLOWED_MASK: ACCESS_MASK = .{
1930 .STANDARD = .{ .RIGHTS = .READ },
1931 .SPECIFIC = .{ .TOKEN = .{
1932 .QUERY = true,
1933 .QUERY_SOURCE = true,
1934 .DUPLICATE = true,
1935 .IMPERSONATE = true,
1936 } },
1937 };
1938 };
1939
1940 pub const JobObject = packed struct(u16) {
1941 ASSIGN_PROCESS: bool = false,
1942 SET_ATTRIBUTES: bool = false,
1943 QUERY: bool = false,
1944 TERMINATE: bool = false,
1945 SET_SECURITY_ATTRIBUTES: bool = false,
1946 IMPERSONATE: bool = false,
1947 Reserved6: u10 = 0,
1948
1949 pub const ALL_ACCESS: ACCESS_MASK = .{
1950 .STANDARD = .{
1951 .RIGHTS = .REQUIRED,
1952 .SYNCHRONIZE = true,
1953 },
1954 .SPECIFIC = .{ .JOB_OBJECT = .{
1955 .ASSIGN_PROCESS = true,
1956 .SET_ATTRIBUTES = true,
1957 .QUERY = true,
1958 .TERMINATE = true,
1959 .SET_SECURITY_ATTRIBUTES = true,
1960 .IMPERSONATE = true,
1961 } },
1962 };
1963 };
1964
1965 pub const Mutant = packed struct(u16) {
1966 QUERY_STATE: bool = false,
1967 Reserved1: u15 = 0,
1968
1969 pub const ALL_ACCESS: ACCESS_MASK = .{
1970 .STANDARD = .{
1971 .RIGHTS = .REQUIRED,
1972 .SYNCHRONIZE = true,
1973 },
1974 .SPECIFIC = .{ .MUTANT = .{
1975 .QUERY_STATE = true,
1976 } },
1977 };
1978 };
1979
1980 pub const Timer = packed struct(u16) {
1981 QUERY_STATE: bool = false,
1982 MODIFY_STATE: bool = false,
1983 Reserved2: u14 = 0,
1984
1985 pub const ALL_ACCESS: ACCESS_MASK = .{
1986 .STANDARD = .{
1987 .RIGHTS = .REQUIRED,
1988 .SYNCHRONIZE = true,
1989 },
1990 .SPECIFIC = .{ .TIMER = .{
1991 .QUERY_STATE = true,
1992 .MODIFY_STATE = true,
1993 } },
1994 };
1995 };
1996
1997 pub const IoCompletion = packed struct(u16) {
1998 Reserved0: u1 = 0,
1999 MODIFY_STATE: bool = false,
2000 Reserved2: u14 = 0,
2001
2002 pub const ALL_ACCESS: ACCESS_MASK = .{
2003 .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true },
2004 .SPECIFIC = .{ .IO_COMPLETION = .{
2005 .Reserved0 = maxInt(@FieldType(IoCompletion, "Reserved0")),
2006 .MODIFY_STATE = true,
2007 } },
2008 };
2009 };
2010
2011 pub const RIGHTS_ALL: Specific = .{ .bits = maxInt(@FieldType(Specific, "bits")) };
2012 };
2013
2014 pub const Standard = packed struct(u5) {
2015 RIGHTS: Rights = .{},
2016 SYNCHRONIZE: bool = false,
2017
2018 pub const RIGHTS_ALL: Standard = .{
2019 .RIGHTS = .ALL,
2020 .SYNCHRONIZE = true,
2021 };
2022
2023 pub const Rights = packed struct(u4) {
2024 DELETE: bool = false,
2025 READ_CONTROL: bool = false,
2026 WRITE_DAC: bool = false,
2027 WRITE_OWNER: bool = false,
2028
2029 pub const REQUIRED: Rights = .{
2030 .DELETE = true,
2031 .READ_CONTROL = true,
2032 .WRITE_DAC = true,
2033 .WRITE_OWNER = true,
2034 };
2035
2036 pub const READ: Rights = .{
2037 .READ_CONTROL = true,
2038 };
2039 pub const WRITE: Rights = .{
2040 .READ_CONTROL = true,
2041 };
2042 pub const EXECUTE: Rights = .{
2043 .READ_CONTROL = true,
2044 };
2045
2046 pub const ALL = REQUIRED;
2047 };
2048 };
2049
2050 pub const Generic = packed struct(u4) {
2051 ALL: bool = false,
2052 EXECUTE: bool = false,
2053 WRITE: bool = false,
2054 READ: bool = false,
2055 };
2056};
2057
2058pub const DEVICE_TYPE = packed struct(ULONG) {
2059 FileDevice: CTL_CODE.FILE_DEVICE,
2060 Reserved16: u16 = 0,
2061};
2062
2063pub const FS_INFORMATION_CLASS = enum(c_int) {
2064 Volume = 1,
2065 Label = 2,
2066 Size = 3,
2067 Device = 4,
2068 Attribute = 5,
2069 Control = 6,
2070 FullSize = 7,
2071 ObjectId = 8,
2072 DriverPath = 9,
2073 VolumeFlags = 10,
2074 SectorSize = 11,
2075 DataCopy = 12,
2076 MetadataSize = 13,
2077 FullSizeEx = 14,
2078 Guid = 15,
2079 _,
2080
2081 pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".fields.len;
2082};
2083
2084pub const SECTION_INHERIT = enum(c_int) {
2085 Share = 1,
2086 Unmap = 2,
2087};
2088
2089pub const PAGE = packed struct(ULONG) {
2090 NOACCESS: bool = false,
2091 READONLY: bool = false,
2092 READWRITE: bool = false,
2093 WRITECOPY: bool = false,
2094
2095 EXECUTE: bool = false,
2096 EXECUTE_READ: bool = false,
2097 EXECUTE_READWRITE: bool = false,
2098 EXECUTE_WRITECOPY: bool = false,
2099
2100 GUARD: bool = false,
2101 NOCACHE: bool = false,
2102 WRITECOMBINE: bool = false,
2103
2104 GRAPHICS_NOACCESS: bool = false,
2105 GRAPHICS_READONLY: bool = false,
2106 GRAPHICS_READWRITE: bool = false,
2107 GRAPHICS_EXECUTE: bool = false,
2108 GRAPHICS_EXECUTE_READ: bool = false,
2109 GRAPHICS_EXECUTE_READWRITE: bool = false,
2110 GRAPHICS_COHERENT: bool = false,
2111 GRAPHICS_NOCACHE: bool = false,
2112
2113 Reserved19: u12 = 0,
2114
2115 REVERT_TO_FILE_MAP: bool = false,
2116};
2117
2118pub const MEM = struct {
2119 pub const ALLOCATE = packed struct(ULONG) {
2120 Reserved0: u12 = 0,
2121 COMMIT: bool = false,
2122 RESERVE: bool = false,
2123 REPLACE_PLACEHOLDER: bool = false,
2124 Reserved15: u3 = 0,
2125 RESERVE_PLACEHOLDER: bool = false,
2126 RESET: bool = false,
2127 TOP_DOWN: bool = false,
2128 WRITE_WATCH: bool = false,
2129 PHYSICAL: bool = false,
2130 Reserved23: u1 = 0,
2131 RESET_UNDO: bool = false,
2132 Reserved25: u4 = 0,
2133 LARGE_PAGES: bool = false,
2134 Reserved30: u1 = 0,
2135 @"4MB_PAGES": bool = false,
2136
2137 pub const @"64K_PAGES": ALLOCATE = .{
2138 .LARGE_PAGES = true,
2139 .PHYSICAL = true,
2140 };
2141 };
2142
2143 pub const FREE = packed struct(ULONG) {
2144 COALESCE_PLACEHOLDERS: bool = false,
2145 PRESERVE_PLACEHOLDER: bool = false,
2146 Reserved2: u12 = 0,
2147 DECOMMIT: bool = false,
2148 RELEASE: bool = false,
2149 FREE: bool = false,
2150 Reserved17: u15 = 0,
2151 };
2152
2153 pub const MAP = packed struct(ULONG) {
2154 Reserved0: u13 = 0,
2155 RESERVE: bool = false,
2156 REPLACE_PLACEHOLDER: bool = false,
2157 Reserved15: u14 = 0,
2158 LARGE_PAGES: bool = false,
2159 Reserved30: u2 = 0,
2160 };
2161
2162 pub const UNMAP = packed struct(ULONG) {
2163 WITH_TRANSIENT_BOOST: bool = false,
2164 PRESERVE_PLACEHOLDER: bool = false,
2165 Reserved2: u30 = 0,
2166 };
2167
2168 pub const EXTENDED_PARAMETER = extern struct {
2169 s: packed struct(ULONG64) {
2170 Type: TYPE,
2171 Reserved: u56,
2172 },
2173 u: extern union {
2174 ULong64: ULONG64,
2175 Pointer: PVOID,
2176 Size: SIZE_T,
2177 Handle: HANDLE,
2178 ULong: ULONG,
2179 },
2180
2181 pub const TYPE = enum(u8) {
2182 InvalidType = 0,
2183 AddressRequirements,
2184 NumaNode,
2185 PartitionHandle,
2186 UserPhysicalHandle,
2187 AttributeFlags,
2188 ImageMachine,
2189 _,
2190
2191 pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".fields.len;
2192 };
2193 };
2194};
2195
2196pub const SEC = packed struct(ULONG) {
2197 Reserved0: u17 = 0,
2198 HUGE_PAGES: bool = false,
2199 PARTITION_OWNER_HANDLE: bool = false,
2200 @"64K_PAGES": bool = false,
2201 Reserved19: u3 = 0,
2202 FILE: bool = false,
2203 IMAGE: bool = false,
2204 PROTECTED_IMAGE: bool = false,
2205 RESERVE: bool = false,
2206 COMMIT: bool = false,
2207 NOCACHE: bool = false,
2208 Reserved29: u1 = 0,
2209 WRITECOMBINE: bool = false,
2210 LARGE_PAGES: bool = false,
2211
2212 pub const IMAGE_NO_EXECUTE: SEC = .{
2213 .IMAGE = true,
2214 .NOCACHE = true,
2215 };
2216};
2217
2218pub const ERESOURCE = opaque {};
2219
2220// ref: shared/ntdef.h
2221
2222pub const EVENT_TYPE = enum(c_int) {
2223 Notification,
2224 Synchronization,
2225};
2226
2227pub const TIMER_TYPE = enum(c_int) {
2228 Notification,
2229 Synchronization,
2230};
2231
2232pub const WAIT_TYPE = enum(c_int) {
2233 All,
2234 Any,
2235};
2236
2237pub const LOGICAL = ULONG;
2238
2239pub const NTSTATUS = @import("windows/ntstatus.zig").NTSTATUS;
2240
2241// ref: um/heapapi.h
2242
2243pub fn GetProcessHeap() ?*HEAP {
2244 return peb().ProcessHeap;
2245}
2246
2247// ref: um/winternl.h
2248
2249pub const OBJECT_ATTRIBUTES = extern struct {
2250 Length: ULONG,
2251 RootDirectory: ?HANDLE,
2252 ObjectName: *UNICODE_STRING,
2253 Attributes: ATTRIBUTES,
2254 SecurityDescriptor: ?*anyopaque,
2255 SecurityQualityOfService: ?*anyopaque,
2256
2257 // Valid values for the Attributes field
2258 pub const ATTRIBUTES = packed struct(ULONG) {
2259 Reserved0: u1 = 0,
2260 INHERIT: bool = false,
2261 Reserved2: u2 = 0,
2262 PERMANENT: bool = false,
2263 EXCLUSIVE: bool = false,
2264 /// If name-lookup code should ignore the case of the ObjectName member rather than performing an exact-match search.
2265 CASE_INSENSITIVE: bool = true,
2266 OPENIF: bool = false,
2267 OPENLINK: bool = false,
2268 KERNEL_HANDLE: bool = false,
2269 FORCE_ACCESS_CHECK: bool = false,
2270 IGNORE_IMPERSONATED_DEVICEMAP: bool = false,
2271 DONT_REPARSE: bool = false,
2272 Reserved13: u19 = 0,
2273
2274 pub const VALID_ATTRIBUTES: ATTRIBUTES = .{
2275 .INHERIT = true,
2276 .PERMANENT = true,
2277 .EXCLUSIVE = true,
2278 .CASE_INSENSITIVE = true,
2279 .OPENIF = true,
2280 .OPENLINK = true,
2281 .KERNEL_HANDLE = true,
2282 .FORCE_ACCESS_CHECK = true,
2283 .IGNORE_IMPERSONATED_DEVICEMAP = true,
2284 .DONT_REPARSE = true,
2285 };
2286 };
2287};
2288
2289// ref none
342290
35pub const OpenError = error{2291pub const OpenError = error{
36 IsDir,2292 IsDir,
...@@ -52,8 +2308,8 @@ pub const OpenFileOptions = struct {...@@ -52,8 +2308,8 @@ pub const OpenFileOptions = struct {
52 access_mask: ACCESS_MASK,2308 access_mask: ACCESS_MASK,
53 dir: ?HANDLE = null,2309 dir: ?HANDLE = null,
54 sa: ?*SECURITY_ATTRIBUTES = null,2310 sa: ?*SECURITY_ATTRIBUTES = null,
55 share_access: ULONG = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,2311 share_access: FILE.SHARE = .VALID_FLAGS,
56 creation: ULONG,2312 creation: FILE.CREATE_DISPOSITION,
57 /// If true, tries to open path as a directory.2313 /// If true, tries to open path as a directory.
58 /// Defaults to false.2314 /// Defaults to false.
59 filter: Filter = .file_only,2315 filter: Filter = .file_only,
...@@ -82,32 +2338,22 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN...@@ -82,32 +2338,22 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN
82 var result: HANDLE = undefined;2338 var result: HANDLE = undefined;
832339
84 const path_len_bytes = math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong;2340 const path_len_bytes = math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong;
85 var nt_name = UNICODE_STRING{2341 var nt_name: UNICODE_STRING = .{
86 .Length = path_len_bytes,2342 .Length = path_len_bytes,
87 .MaximumLength = path_len_bytes,2343 .MaximumLength = path_len_bytes,
88 .Buffer = @constCast(sub_path_w.ptr),2344 .Buffer = @constCast(sub_path_w.ptr),
89 };2345 };
90 var attr = OBJECT_ATTRIBUTES{2346 const attr: OBJECT_ATTRIBUTES = .{
91 .Length = @sizeOf(OBJECT_ATTRIBUTES),2347 .Length = @sizeOf(OBJECT_ATTRIBUTES),
92 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else options.dir,2348 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else options.dir,
93 .Attributes = if (options.sa) |ptr| blk: { // Note we do not use OBJ_CASE_INSENSITIVE here.2349 .Attributes = .{
94 const inherit: ULONG = if (ptr.bInheritHandle == TRUE) OBJ_INHERIT else 0;2350 .INHERIT = if (options.sa) |sa| sa.bInheritHandle != FALSE else false,
95 break :blk inherit;2351 },
96 } else 0,
97 .ObjectName = &nt_name,2352 .ObjectName = &nt_name,
98 .SecurityDescriptor = if (options.sa) |ptr| ptr.lpSecurityDescriptor else null,2353 .SecurityDescriptor = if (options.sa) |ptr| ptr.lpSecurityDescriptor else null,
99 .SecurityQualityOfService = null,2354 .SecurityQualityOfService = null,
100 };2355 };
101 var io: IO_STATUS_BLOCK = undefined;2356 var io: IO_STATUS_BLOCK = undefined;
102 const blocking_flag: ULONG = FILE_SYNCHRONOUS_IO_NONALERT;
103 const file_or_dir_flag: ULONG = switch (options.filter) {
104 .file_only => FILE_NON_DIRECTORY_FILE,
105 .dir_only => FILE_DIRECTORY_FILE,
106 .any => 0,
107 };
108 // If we're not following symlinks, we need to ensure we don't pass in any synchronization flags such as FILE_SYNCHRONOUS_IO_NONALERT.
109 const flags: ULONG = if (options.follow_symlinks) file_or_dir_flag | blocking_flag else file_or_dir_flag | FILE_OPEN_REPARSE_POINT;
110
111 while (true) {2357 while (true) {
112 const rc = ntdll.NtCreateFile(2358 const rc = ntdll.NtCreateFile(
113 &result,2359 &result,
...@@ -115,10 +2361,15 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN...@@ -115,10 +2361,15 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN
115 &attr,2361 &attr,
116 &io,2362 &io,
117 null,2363 null,
118 FILE_ATTRIBUTE_NORMAL,2364 .{ .NORMAL = true },
119 options.share_access,2365 options.share_access,
120 options.creation,2366 options.creation,
121 flags,2367 .{
2368 .DIRECTORY_FILE = options.filter == .dir_only,
2369 .NON_DIRECTORY_FILE = options.filter == .file_only,
2370 .IO = if (options.follow_symlinks) .SYNCHRONOUS_NONALERT else .ASYNCHRONOUS,
2371 .OPEN_REPARSE_POINT = !options.follow_symlinks,
2372 },
122 null,2373 null,
123 0,2374 0,
124 );2375 );
...@@ -201,16 +2452,16 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C...@@ -201,16 +2452,16 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
201 const dev_handle = opt_dev_handle orelse blk: {2452 const dev_handle = opt_dev_handle orelse blk: {
202 const str = std.unicode.utf8ToUtf16LeStringLiteral("\\Device\\NamedPipe\\");2453 const str = std.unicode.utf8ToUtf16LeStringLiteral("\\Device\\NamedPipe\\");
203 const len: u16 = @truncate(str.len * @sizeOf(u16));2454 const len: u16 = @truncate(str.len * @sizeOf(u16));
204 const name = UNICODE_STRING{2455 const name: UNICODE_STRING = .{
205 .Length = len,2456 .Length = len,
206 .MaximumLength = len,2457 .MaximumLength = len,
207 .Buffer = @ptrCast(@constCast(str)),2458 .Buffer = @ptrCast(@constCast(str)),
208 };2459 };
209 const attrs = OBJECT_ATTRIBUTES{2460 const attrs: OBJECT_ATTRIBUTES = .{
210 .ObjectName = @constCast(&name),2461 .ObjectName = @constCast(&name),
211 .Length = @sizeOf(OBJECT_ATTRIBUTES),2462 .Length = @sizeOf(OBJECT_ATTRIBUTES),
212 .RootDirectory = null,2463 .RootDirectory = null,
213 .Attributes = 0,2464 .Attributes = .{},
214 .SecurityDescriptor = null,2465 .SecurityDescriptor = null,
215 .SecurityQualityOfService = null,2466 .SecurityQualityOfService = null,
216 };2467 };
...@@ -219,14 +2470,17 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C...@@ -219,14 +2470,17 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
219 var handle: HANDLE = undefined;2470 var handle: HANDLE = undefined;
220 switch (ntdll.NtCreateFile(2471 switch (ntdll.NtCreateFile(
221 &handle,2472 &handle,
222 GENERIC_READ | SYNCHRONIZE,2473 .{
2474 .STANDARD = .{ .SYNCHRONIZE = true },
2475 .GENERIC = .{ .READ = true },
2476 },
223 @constCast(&attrs),2477 @constCast(&attrs),
224 &iosb,2478 &iosb,
225 null,2479 null,
226 0,2480 .{},
227 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,2481 .VALID_FLAGS,
228 FILE_OPEN,2482 .OPEN,
229 FILE_SYNCHRONOUS_IO_NONALERT,2483 .{ .IO = .SYNCHRONOUS_NONALERT },
230 null,2484 null,
231 0,2485 0,
232 )) {2486 )) {
...@@ -242,16 +2496,15 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C...@@ -242,16 +2496,15 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
242 } else break :blk handle;2496 } else break :blk handle;
243 };2497 };
2442498
245 const name = UNICODE_STRING{ .Buffer = null, .Length = 0, .MaximumLength = 0 };2499 const name: UNICODE_STRING = .{ .Buffer = null, .Length = 0, .MaximumLength = 0 };
246 var attrs = OBJECT_ATTRIBUTES{2500 var attrs: OBJECT_ATTRIBUTES = .{
247 .ObjectName = @constCast(&name),2501 .ObjectName = @constCast(&name),
248 .Length = @sizeOf(OBJECT_ATTRIBUTES),2502 .Length = @sizeOf(OBJECT_ATTRIBUTES),
249 .RootDirectory = dev_handle,2503 .RootDirectory = dev_handle,
250 .Attributes = OBJ_CASE_INSENSITIVE,2504 .Attributes = .{ .INHERIT = sattr.bInheritHandle != FALSE },
251 .SecurityDescriptor = sattr.lpSecurityDescriptor,2505 .SecurityDescriptor = sattr.lpSecurityDescriptor,
252 .SecurityQualityOfService = null,2506 .SecurityQualityOfService = null,
253 };2507 };
254 if (sattr.bInheritHandle != 0) attrs.Attributes |= OBJ_INHERIT;
2552508
256 // 120 second relative timeout in 100ns units.2509 // 120 second relative timeout in 100ns units.
257 const default_timeout: LARGE_INTEGER = (-120 * std.time.ns_per_s) / 100;2510 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...@@ -259,15 +2512,21 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
259 var read: HANDLE = undefined;2512 var read: HANDLE = undefined;
260 switch (ntdll.NtCreateNamedPipeFile(2513 switch (ntdll.NtCreateNamedPipeFile(
261 &read,2514 &read,
262 GENERIC_READ | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,2515 .{
2516 .SPECIFIC = .{ .FILE_PIPE = .{
2517 .WRITE_ATTRIBUTES = true,
2518 } },
2519 .STANDARD = .{ .SYNCHRONIZE = true },
2520 .GENERIC = .{ .READ = true },
2521 },
263 &attrs,2522 &attrs,
264 &iosb,2523 &iosb,
265 FILE_SHARE_READ | FILE_SHARE_WRITE,2524 .{ .READ = true, .WRITE = true },
266 FILE_CREATE,2525 .CREATE,
267 FILE_SYNCHRONOUS_IO_NONALERT,2526 .{ .IO = .SYNCHRONOUS_NONALERT },
268 FILE_PIPE_BYTE_STREAM_TYPE,2527 .{ .TYPE = .BYTE_STREAM },
269 FILE_PIPE_BYTE_STREAM_MODE,2528 .{ .MODE = .BYTE_STREAM },
270 FILE_PIPE_QUEUE_OPERATION,2529 .{ .OPERATION = .QUEUE },
271 1,2530 1,
272 4096,2531 4096,
273 4096,2532 4096,
...@@ -285,14 +2544,23 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C...@@ -285,14 +2544,23 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
285 var write: HANDLE = undefined;2544 var write: HANDLE = undefined;
286 switch (ntdll.NtCreateFile(2545 switch (ntdll.NtCreateFile(
287 &write,2546 &write,
288 GENERIC_WRITE | SYNCHRONIZE | FILE_READ_ATTRIBUTES,2547 .{
2548 .SPECIFIC = .{ .FILE_PIPE = .{
2549 .READ_ATTRIBUTES = true,
2550 } },
2551 .STANDARD = .{ .SYNCHRONIZE = true },
2552 .GENERIC = .{ .WRITE = true },
2553 },
289 &attrs,2554 &attrs,
290 &iosb,2555 &iosb,
291 null,2556 null,
292 0,2557 .{},
293 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,2558 .VALID_FLAGS,
294 FILE_OPEN,2559 .OPEN,
295 FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE,2560 .{
2561 .IO = .SYNCHRONOUS_NONALERT,
2562 .NON_DIRECTORY_FILE = true,
2563 },
296 null,2564 null,
297 0,2565 0,
298 )) {2566 )) {
...@@ -311,6 +2579,15 @@ pub const DeviceIoControlError = error{...@@ -311,6 +2579,15 @@ pub const DeviceIoControlError = error{
311 /// The volume does not contain a recognized file system. File system2579 /// The volume does not contain a recognized file system. File system
312 /// drivers might not be loaded, or the volume may be corrupt.2580 /// drivers might not be loaded, or the volume may be corrupt.
313 UnrecognizedVolume,2581 UnrecognizedVolume,
2582 Pending,
2583 /// Attempted to connect a named pipe in the "closing" state, meaning a previous client has
2584 /// has closed their handle but we have not yet disconnected the pipe.
2585 PipeClosing,
2586 /// Attempted to connect a named pipe in the "connected" state, meaning a client has already
2587 /// opened the pipe; there is a good connection between client and server.
2588 PipeAlreadyConnected,
2589 /// Attempted to connect a non-blocking named pipe which is already listening for connections.
2590 PipeAlreadyListening,
314 Unexpected,2591 Unexpected,
315};2592};
3162593
...@@ -319,56 +2596,55 @@ pub const DeviceIoControlError = error{...@@ -319,56 +2596,55 @@ pub const DeviceIoControlError = error{
319/// as a direct substitute for that call.2596/// as a direct substitute for that call.
320/// TODO work out if we need to expose other arguments to the underlying syscalls.2597/// TODO work out if we need to expose other arguments to the underlying syscalls.
321pub fn DeviceIoControl(2598pub fn DeviceIoControl(
322 h: HANDLE,2599 device: HANDLE,
323 ioControlCode: ULONG,2600 io_control_code: CTL_CODE,
324 in: ?[]const u8,2601 opts: struct {
325 out: ?[]u8,2602 event: ?HANDLE = null,
2603 apc_routine: ?*const IO_APC_ROUTINE = null,
2604 apc_context: ?*anyopaque = null,
2605 io_status_block: ?*IO_STATUS_BLOCK = null,
2606 in: []const u8 = &.{},
2607 out: []u8 = &.{},
2608 },
326) DeviceIoControlError!void {2609) DeviceIoControlError!void {
327 // Logic from: https://doxygen.reactos.org/d3/d74/deviceio_8c.html2610 var io_status_block: IO_STATUS_BLOCK = undefined;
328 const is_fsctl = (ioControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM;2611 const rc = switch (io_control_code.DeviceType) {
3292612 .FILE_SYSTEM, .NAMED_PIPE => ntdll.NtFsControlFile(
330 var io: IO_STATUS_BLOCK = undefined;2613 device,
331 const in_ptr = if (in) |i| i.ptr else null;2614 opts.event,
332 const in_len = if (in) |i| @as(ULONG, @intCast(i.len)) else 0;2615 opts.apc_routine,
333 const out_ptr = if (out) |o| o.ptr else null;2616 opts.apc_context,
334 const out_len = if (out) |o| @as(ULONG, @intCast(o.len)) else 0;2617 opts.io_status_block orelse &io_status_block,
3352618 io_control_code,
336 const rc = blk: {2619 if (opts.in.len > 0) opts.in.ptr else null,
337 if (is_fsctl) {2620 @intCast(opts.in.len),
338 break :blk ntdll.NtFsControlFile(2621 if (opts.out.len > 0) opts.out.ptr else null,
339 h,2622 @intCast(opts.out.len),
340 null,2623 ),
341 null,2624 else => ntdll.NtDeviceIoControlFile(
342 null,2625 device,
343 &io,2626 opts.event,
344 ioControlCode,2627 opts.apc_routine,
345 in_ptr,2628 opts.apc_context,
346 in_len,2629 opts.io_status_block orelse &io_status_block,
347 out_ptr,2630 io_control_code,
348 out_len,2631 if (opts.in.len > 0) opts.in.ptr else null,
349 );2632 @intCast(opts.in.len),
350 } else {2633 if (opts.out.len > 0) opts.out.ptr else null,
351 break :blk ntdll.NtDeviceIoControlFile(2634 @intCast(opts.out.len),
352 h,2635 ),
353 null,
354 null,
355 null,
356 &io,
357 ioControlCode,
358 in_ptr,
359 in_len,
360 out_ptr,
361 out_len,
362 );
363 }
364 };2636 };
365 switch (rc) {2637 switch (rc) {
366 .SUCCESS => {},2638 .SUCCESS => {},
2639 .PIPE_CLOSING => return error.PipeClosing,
2640 .PIPE_CONNECTED => return error.PipeAlreadyConnected,
2641 .PIPE_LISTENING => return error.PipeAlreadyListening,
367 .PRIVILEGE_NOT_HELD => return error.AccessDenied,2642 .PRIVILEGE_NOT_HELD => return error.AccessDenied,
368 .ACCESS_DENIED => return error.AccessDenied,2643 .ACCESS_DENIED => return error.AccessDenied,
369 .INVALID_DEVICE_REQUEST => return error.AccessDenied, // Not supported by the underlying filesystem2644 .INVALID_DEVICE_REQUEST => return error.AccessDenied, // Not supported by the underlying filesystem
370 .INVALID_PARAMETER => unreachable,2645 .INVALID_PARAMETER => unreachable,
371 .UNRECOGNIZED_VOLUME => return error.UnrecognizedVolume,2646 .UNRECOGNIZED_VOLUME => return error.UnrecognizedVolume,
2647 .PENDING => return error.Pending,
372 else => return unexpectedStatus(rc),2648 else => return unexpectedStatus(rc),
373 }2649 }
374}2650}
...@@ -704,7 +2980,7 @@ pub const SetCurrentDirectoryError = error{...@@ -704,7 +2980,7 @@ pub const SetCurrentDirectoryError = error{
704pub fn SetCurrentDirectory(path_name: []const u16) SetCurrentDirectoryError!void {2980pub fn SetCurrentDirectory(path_name: []const u16) SetCurrentDirectoryError!void {
705 const path_len_bytes = math.cast(u16, path_name.len * 2) orelse return error.NameTooLong;2981 const path_len_bytes = math.cast(u16, path_name.len * 2) orelse return error.NameTooLong;
7062982
707 var nt_name = UNICODE_STRING{2983 var nt_name: UNICODE_STRING = .{
708 .Length = path_len_bytes,2984 .Length = path_len_bytes,
709 .MaximumLength = path_len_bytes,2985 .MaximumLength = path_len_bytes,
710 .Buffer = @constCast(path_name.ptr),2986 .Buffer = @constCast(path_name.ptr),
...@@ -780,7 +3056,7 @@ pub fn CreateSymbolicLink(...@@ -780,7 +3056,7 @@ pub fn CreateSymbolicLink(
780 is_directory: bool,3056 is_directory: bool,
781) CreateSymbolicLinkError!void {3057) CreateSymbolicLinkError!void {
782 const SYMLINK_DATA = extern struct {3058 const SYMLINK_DATA = extern struct {
783 ReparseTag: ULONG,3059 ReparseTag: IO_REPARSE_TAG,
784 ReparseDataLength: USHORT,3060 ReparseDataLength: USHORT,
785 Reserved: USHORT,3061 Reserved: USHORT,
786 SubstituteNameOffset: USHORT,3062 SubstituteNameOffset: USHORT,
...@@ -791,9 +3067,12 @@ pub fn CreateSymbolicLink(...@@ -791,9 +3067,12 @@ pub fn CreateSymbolicLink(
791 };3067 };
7923068
793 const symlink_handle = OpenFile(sym_link_path, .{3069 const symlink_handle = OpenFile(sym_link_path, .{
794 .access_mask = SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE,3070 .access_mask = .{
3071 .STANDARD = .{ .SYNCHRONIZE = true },
3072 .GENERIC = .{ .WRITE = true, .READ = true },
3073 },
795 .dir = dir,3074 .dir = dir,
796 .creation = FILE_CREATE,3075 .creation = .CREATE,
797 .filter = if (is_directory) .dir_only else .file_only,3076 .filter = if (is_directory) .dir_only else .file_only,
798 }) catch |err| switch (err) {3077 }) catch |err| switch (err) {
799 error.IsDir => return error.PathAlreadyExists,3078 error.IsDir => return error.PathAlreadyExists,
...@@ -845,8 +3124,8 @@ pub fn CreateSymbolicLink(...@@ -845,8 +3124,8 @@ pub fn CreateSymbolicLink(
845 const buf_len = @sizeOf(SYMLINK_DATA) + final_target_path.len * 4;3124 const buf_len = @sizeOf(SYMLINK_DATA) + final_target_path.len * 4;
846 const header_len = @sizeOf(ULONG) + @sizeOf(USHORT) * 2;3125 const header_len = @sizeOf(ULONG) + @sizeOf(USHORT) * 2;
847 const target_is_absolute = std.fs.path.isAbsoluteWindowsWtf16(final_target_path);3126 const target_is_absolute = std.fs.path.isAbsoluteWindowsWtf16(final_target_path);
848 const symlink_data = SYMLINK_DATA{3127 const symlink_data: SYMLINK_DATA = .{
849 .ReparseTag = IO_REPARSE_TAG_SYMLINK,3128 .ReparseTag = .SYMLINK,
850 .ReparseDataLength = @intCast(buf_len - header_len),3129 .ReparseDataLength = @intCast(buf_len - header_len),
851 .Reserved = 0,3130 .Reserved = 0,
852 .SubstituteNameOffset = @intCast(final_target_path.len * 2),3131 .SubstituteNameOffset = @intCast(final_target_path.len * 2),
...@@ -860,7 +3139,13 @@ pub fn CreateSymbolicLink(...@@ -860,7 +3139,13 @@ pub fn CreateSymbolicLink(
860 @memcpy(buffer[@sizeOf(SYMLINK_DATA)..][0 .. final_target_path.len * 2], @as([*]const u8, @ptrCast(final_target_path)));3139 @memcpy(buffer[@sizeOf(SYMLINK_DATA)..][0 .. final_target_path.len * 2], @as([*]const u8, @ptrCast(final_target_path)));
861 const paths_start = @sizeOf(SYMLINK_DATA) + final_target_path.len * 2;3140 const paths_start = @sizeOf(SYMLINK_DATA) + final_target_path.len * 2;
862 @memcpy(buffer[paths_start..][0 .. final_target_path.len * 2], @as([*]const u8, @ptrCast(final_target_path)));3141 @memcpy(buffer[paths_start..][0 .. final_target_path.len * 2], @as([*]const u8, @ptrCast(final_target_path)));
863 _ = try DeviceIoControl(symlink_handle, FSCTL_SET_REPARSE_POINT, buffer[0..buf_len], null);3142 _ = DeviceIoControl(symlink_handle, FSCTL.SET_REPARSE_POINT, .{ .in = buffer[0..buf_len] }) catch |err| switch (err) {
3143 error.PipeClosing => unreachable,
3144 error.PipeAlreadyConnected => unreachable,
3145 error.PipeAlreadyListening => unreachable,
3146 error.Pending => unreachable,
3147 else => |e| return e,
3148 };
864}3149}
8653150
866pub const ReadLinkError = error{3151pub const ReadLinkError = error{
...@@ -878,9 +3163,14 @@ pub const ReadLinkError = error{...@@ -878,9 +3163,14 @@ pub const ReadLinkError = error{
878/// is safe to reuse a single buffer for both.3163/// is safe to reuse a single buffer for both.
879pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u16) ReadLinkError![]u16 {3164pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u16) ReadLinkError![]u16 {
880 const result_handle = OpenFile(sub_path_w, .{3165 const result_handle = OpenFile(sub_path_w, .{
881 .access_mask = FILE_READ_ATTRIBUTES | SYNCHRONIZE,3166 .access_mask = .{
3167 .SPECIFIC = .{ .FILE = .{
3168 .READ_ATTRIBUTES = true,
3169 } },
3170 .STANDARD = .{ .SYNCHRONIZE = true },
3171 },
882 .dir = dir,3172 .dir = dir,
883 .creation = FILE_OPEN,3173 .creation = .OPEN,
884 .follow_symlinks = false,3174 .follow_symlinks = false,
885 .filter = .any,3175 .filter = .any,
886 }) catch |err| switch (err) {3176 }) catch |err| switch (err) {
...@@ -894,15 +3184,20 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u16) ReadLi...@@ -894,15 +3184,20 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u16) ReadLi
894 defer CloseHandle(result_handle);3184 defer CloseHandle(result_handle);
8953185
896 var reparse_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 align(@alignOf(REPARSE_DATA_BUFFER)) = undefined;3186 var reparse_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 align(@alignOf(REPARSE_DATA_BUFFER)) = undefined;
897 _ = DeviceIoControl(result_handle, FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..]) catch |err| switch (err) {3187 _ = DeviceIoControl(result_handle, FSCTL.GET_REPARSE_POINT, .{ .out = reparse_buf[0..] }) catch |err| switch (err) {
3188 error.PipeClosing => unreachable,
3189 error.PipeAlreadyConnected => unreachable,
3190 error.PipeAlreadyListening => unreachable,
898 error.AccessDenied => return error.Unexpected,3191 error.AccessDenied => return error.Unexpected,
899 error.UnrecognizedVolume => return error.Unexpected,3192 error.UnrecognizedVolume => return error.Unexpected,
3193 error.Pending => unreachable,
900 else => |e| return e,3194 else => |e| return e,
901 };3195 };
9023196
903 const reparse_struct: *const REPARSE_DATA_BUFFER = @ptrCast(@alignCast(&reparse_buf[0]));3197 const reparse_struct: *const REPARSE_DATA_BUFFER = @ptrCast(@alignCast(&reparse_buf[0]));
904 switch (reparse_struct.ReparseTag) {3198 const IoReparseTagInt = @typeInfo(IO_REPARSE_TAG).@"struct".backing_integer.?;
905 IO_REPARSE_TAG_SYMLINK => {3199 switch (@as(IoReparseTagInt, @bitCast(reparse_struct.ReparseTag))) {
3200 @as(IoReparseTagInt, @bitCast(IO_REPARSE_TAG.SYMLINK)) => {
906 const buf: *const SYMBOLIC_LINK_REPARSE_BUFFER = @ptrCast(@alignCast(&reparse_struct.DataBuffer[0]));3201 const buf: *const SYMBOLIC_LINK_REPARSE_BUFFER = @ptrCast(@alignCast(&reparse_struct.DataBuffer[0]));
907 const offset = buf.SubstituteNameOffset >> 1;3202 const offset = buf.SubstituteNameOffset >> 1;
908 const len = buf.SubstituteNameLength >> 1;3203 const len = buf.SubstituteNameLength >> 1;
...@@ -910,16 +3205,14 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u16) ReadLi...@@ -910,16 +3205,14 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u16) ReadLi
910 const is_relative = buf.Flags & SYMLINK_FLAG_RELATIVE != 0;3205 const is_relative = buf.Flags & SYMLINK_FLAG_RELATIVE != 0;
911 return parseReadLinkPath(path_buf[offset..][0..len], is_relative, out_buffer);3206 return parseReadLinkPath(path_buf[offset..][0..len], is_relative, out_buffer);
912 },3207 },
913 IO_REPARSE_TAG_MOUNT_POINT => {3208 @as(IoReparseTagInt, @bitCast(IO_REPARSE_TAG.MOUNT_POINT)) => {
914 const buf: *const MOUNT_POINT_REPARSE_BUFFER = @ptrCast(@alignCast(&reparse_struct.DataBuffer[0]));3209 const buf: *const MOUNT_POINT_REPARSE_BUFFER = @ptrCast(@alignCast(&reparse_struct.DataBuffer[0]));
915 const offset = buf.SubstituteNameOffset >> 1;3210 const offset = buf.SubstituteNameOffset >> 1;
916 const len = buf.SubstituteNameLength >> 1;3211 const len = buf.SubstituteNameLength >> 1;
917 const path_buf = @as([*]const u16, &buf.PathBuffer);3212 const path_buf = @as([*]const u16, &buf.PathBuffer);
918 return parseReadLinkPath(path_buf[offset..][0..len], false, out_buffer);3213 return parseReadLinkPath(path_buf[offset..][0..len], false, out_buffer);
919 },3214 },
920 else => {3215 else => return error.UnsupportedReparsePointType,
921 return error.UnsupportedReparsePointType;
922 },
923 }3216 }
924}3217}
9253218
...@@ -956,13 +3249,8 @@ pub const DeleteFileOptions = struct {...@@ -956,13 +3249,8 @@ pub const DeleteFileOptions = struct {
956};3249};
9573250
958pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFileError!void {3251pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFileError!void {
959 const create_options_flags: ULONG = if (options.remove_dir)
960 FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT
961 else
962 FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT; // would we ever want to delete the target instead?
963
964 const path_len_bytes = @as(u16, @intCast(sub_path_w.len * 2));3252 const path_len_bytes = @as(u16, @intCast(sub_path_w.len * 2));
965 var nt_name = UNICODE_STRING{3253 var nt_name: UNICODE_STRING = .{
966 .Length = path_len_bytes,3254 .Length = path_len_bytes,
967 .MaximumLength = path_len_bytes,3255 .MaximumLength = path_len_bytes,
968 // The Windows API makes this mutable, but it will not mutate here.3256 // 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...@@ -978,26 +3266,32 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
978 return error.FileBusy;3266 return error.FileBusy;
979 }3267 }
9803268
981 var attr = OBJECT_ATTRIBUTES{
982 .Length = @sizeOf(OBJECT_ATTRIBUTES),
983 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else options.dir,
984 .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
985 .ObjectName = &nt_name,
986 .SecurityDescriptor = null,
987 .SecurityQualityOfService = null,
988 };
989 var io: IO_STATUS_BLOCK = undefined;3269 var io: IO_STATUS_BLOCK = undefined;
990 var tmp_handle: HANDLE = undefined;3270 var tmp_handle: HANDLE = undefined;
991 var rc = ntdll.NtCreateFile(3271 var rc = ntdll.NtCreateFile(
992 &tmp_handle,3272 &tmp_handle,
993 SYNCHRONIZE | DELETE,3273 .{ .STANDARD = .{
994 &attr,3274 .RIGHTS = .{ .DELETE = true },
3275 .SYNCHRONIZE = true,
3276 } },
3277 &.{
3278 .Length = @sizeOf(OBJECT_ATTRIBUTES),
3279 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else options.dir,
3280 .Attributes = .{},
3281 .ObjectName = &nt_name,
3282 .SecurityDescriptor = null,
3283 .SecurityQualityOfService = null,
3284 },
995 &io,3285 &io,
996 null,3286 null,
997 0,3287 .{},
998 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,3288 .VALID_FLAGS,
999 FILE_OPEN,3289 .OPEN,
1000 create_options_flags,3290 .{
3291 .DIRECTORY_FILE = options.remove_dir,
3292 .NON_DIRECTORY_FILE = !options.remove_dir,
3293 .OPEN_REPARSE_POINT = true, // would we ever want to delete the target instead?
3294 },
1001 null,3295 null,
1002 0,3296 0,
1003 );3297 );
...@@ -1031,18 +3325,17 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil...@@ -1031,18 +3325,17 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
1031 // FileDispositionInformation if the return value lets us know that some aspect of it is not supported.3325 // FileDispositionInformation if the return value lets us know that some aspect of it is not supported.
1032 const need_fallback = need_fallback: {3326 const need_fallback = need_fallback: {
1033 // Deletion with posix semantics if the filesystem supports it.3327 // Deletion with posix semantics if the filesystem supports it.
1034 var info = FILE_DISPOSITION_INFORMATION_EX{3328 const info: FILE.DISPOSITION.INFORMATION.EX = .{ .Flags = .{
1035 .Flags = FILE_DISPOSITION_DELETE |3329 .DELETE = true,
1036 FILE_DISPOSITION_POSIX_SEMANTICS |3330 .POSIX_SEMANTICS = true,
1037 FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE,3331 .IGNORE_READONLY_ATTRIBUTE = true,
1038 };3332 } };
1039
1040 rc = ntdll.NtSetInformationFile(3333 rc = ntdll.NtSetInformationFile(
1041 tmp_handle,3334 tmp_handle,
1042 &io,3335 &io,
1043 &info,3336 &info,
1044 @sizeOf(FILE_DISPOSITION_INFORMATION_EX),3337 @sizeOf(FILE.DISPOSITION.INFORMATION.EX),
1045 .FileDispositionInformationEx,3338 .DispositionEx,
1046 );3339 );
1047 switch (rc) {3340 switch (rc) {
1048 .SUCCESS => return,3341 .SUCCESS => return,
...@@ -1061,16 +3354,15 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil...@@ -1061,16 +3354,15 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
1061 if (need_fallback) {3354 if (need_fallback) {
1062 // Deletion with file pending semantics, which requires waiting or moving3355 // Deletion with file pending semantics, which requires waiting or moving
1063 // files to get them removed (from here).3356 // files to get them removed (from here).
1064 var file_dispo = FILE_DISPOSITION_INFORMATION{3357 const file_dispo: FILE.DISPOSITION.INFORMATION = .{
1065 .DeleteFile = TRUE,3358 .DeleteFile = TRUE,
1066 };3359 };
1067
1068 rc = ntdll.NtSetInformationFile(3360 rc = ntdll.NtSetInformationFile(
1069 tmp_handle,3361 tmp_handle,
1070 &io,3362 &io,
1071 &file_dispo,3363 &file_dispo,
1072 @sizeOf(FILE_DISPOSITION_INFORMATION),3364 @sizeOf(FILE.DISPOSITION.INFORMATION),
1073 .FileDispositionInformation,3365 .Disposition,
1074 );3366 );
1075 }3367 }
1076 switch (rc) {3368 switch (rc) {
...@@ -1112,8 +3404,14 @@ pub fn RenameFile(...@@ -1112,8 +3404,14 @@ pub fn RenameFile(
1112) RenameError!void {3404) RenameError!void {
1113 const src_fd = OpenFile(old_path_w, .{3405 const src_fd = OpenFile(old_path_w, .{
1114 .dir = old_dir_fd,3406 .dir = old_dir_fd,
1115 .access_mask = SYNCHRONIZE | GENERIC_WRITE | DELETE,3407 .access_mask = .{
1116 .creation = FILE_OPEN,3408 .STANDARD = .{
3409 .RIGHTS = .{ .DELETE = true },
3410 .SYNCHRONIZE = true,
3411 },
3412 .GENERIC = .{ .WRITE = true },
3413 },
3414 .creation = .OPEN,
1117 .filter = .any, // This function is supposed to rename both files and directories.3415 .filter = .any, // This function is supposed to rename both files and directories.
1118 .follow_symlinks = false,3416 .follow_symlinks = false,
1119 }) catch |err| switch (err) {3417 }) catch |err| switch (err) {
...@@ -1135,29 +3433,23 @@ pub fn RenameFile(...@@ -1135,29 +3433,23 @@ pub fn RenameFile(
1135 // The strategy here is just to try using FileRenameInformationEx and fall back to3433 // The strategy here is just to try using FileRenameInformationEx and fall back to
1136 // FileRenameInformation if the return value lets us know that some aspect of it is not supported.3434 // FileRenameInformation if the return value lets us know that some aspect of it is not supported.
1137 const need_fallback = need_fallback: {3435 const need_fallback = need_fallback: {
1138 const struct_buf_len = @sizeOf(FILE_RENAME_INFORMATION_EX) + (PATH_MAX_WIDE * 2);3436 const rename_info: FILE.RENAME_INFORMATION = .init(.{
1139 var rename_info_buf: [struct_buf_len]u8 align(@alignOf(FILE_RENAME_INFORMATION_EX)) = undefined;3437 .Flags = .{
1140 const struct_len = @sizeOf(FILE_RENAME_INFORMATION_EX) + new_path_w.len * 2;3438 .REPLACE_IF_EXISTS = replace_if_exists,
1141 if (struct_len > struct_buf_len) return error.NameTooLong;3439 .POSIX_SEMANTICS = true,
11423440 .IGNORE_READONLY_ATTRIBUTE = true,
1143 const rename_info: *FILE_RENAME_INFORMATION_EX = @ptrCast(&rename_info_buf);3441 },
1144 var io_status_block: IO_STATUS_BLOCK = undefined;
1145
1146 var flags: ULONG = FILE_RENAME_POSIX_SEMANTICS | FILE_RENAME_IGNORE_READONLY_ATTRIBUTE;
1147 if (replace_if_exists) flags |= FILE_RENAME_REPLACE_IF_EXISTS;
1148 rename_info.* = .{
1149 .Flags = flags,
1150 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(new_path_w)) null else new_dir_fd,3442 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(new_path_w)) null else new_dir_fd,
1151 .FileNameLength = @intCast(new_path_w.len * 2), // already checked error.NameTooLong3443 .FileName = new_path_w,
1152 .FileName = undefined,3444 });
1153 };3445 var io_status_block: IO_STATUS_BLOCK = undefined;
1154 @memcpy((&rename_info.FileName).ptr, new_path_w);3446 const rename_info_buf = rename_info.toBuffer();
1155 rc = ntdll.NtSetInformationFile(3447 rc = ntdll.NtSetInformationFile(
1156 src_fd,3448 src_fd,
1157 &io_status_block,3449 &io_status_block,
1158 rename_info,3450 rename_info_buf.ptr,
1159 @intCast(struct_len), // already checked for error.NameTooLong3451 @intCast(rename_info_buf.len), // already checked for error.NameTooLong
1160 .FileRenameInformationEx,3452 .RenameEx,
1161 );3453 );
1162 switch (rc) {3454 switch (rc) {
1163 .SUCCESS => return,3455 .SUCCESS => return,
...@@ -1174,28 +3466,19 @@ pub fn RenameFile(...@@ -1174,28 +3466,19 @@ pub fn RenameFile(
1174 };3466 };
11753467
1176 if (need_fallback) {3468 if (need_fallback) {
1177 const struct_buf_len = @sizeOf(FILE_RENAME_INFORMATION) + (PATH_MAX_WIDE * 2);3469 const rename_info: FILE.RENAME_INFORMATION = .init(.{
1178 var rename_info_buf: [struct_buf_len]u8 align(@alignOf(FILE_RENAME_INFORMATION)) = undefined;3470 .Flags = .{ .REPLACE_IF_EXISTS = replace_if_exists },
1179 const struct_len = @sizeOf(FILE_RENAME_INFORMATION) + new_path_w.len * 2;
1180 if (struct_len > struct_buf_len) return error.NameTooLong;
1181
1182 const rename_info: *FILE_RENAME_INFORMATION = @ptrCast(&rename_info_buf);
1183 var io_status_block: IO_STATUS_BLOCK = undefined;
1184
1185 rename_info.* = .{
1186 .Flags = @intFromBool(replace_if_exists),
1187 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(new_path_w)) null else new_dir_fd,3471 .RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(new_path_w)) null else new_dir_fd,
1188 .FileNameLength = @intCast(new_path_w.len * 2), // already checked error.NameTooLong3472 .FileName = new_path_w,
1189 .FileName = undefined,3473 });
1190 };3474 var io_status_block: IO_STATUS_BLOCK = undefined;
1191 @memcpy((&rename_info.FileName).ptr, new_path_w);3475 const rename_info_buf = rename_info.toBuffer();
1192
1193 rc = ntdll.NtSetInformationFile(3476 rc = ntdll.NtSetInformationFile(
1194 src_fd,3477 src_fd,
1195 &io_status_block,3478 &io_status_block,
1196 rename_info,3479 rename_info_buf.ptr,
1197 @intCast(struct_len), // already checked for error.NameTooLong3480 @intCast(rename_info_buf.len), // already checked for error.NameTooLong
1198 .FileRenameInformation,3481 .Rename,
1199 );3482 );
1200 }3483 }
12013484
...@@ -1308,7 +3591,7 @@ pub fn QueryObjectName(handle: HANDLE, out_buffer: []u16) QueryObjectNameError![...@@ -1308,7 +3591,7 @@ pub fn QueryObjectName(handle: HANDLE, out_buffer: []u16) QueryObjectNameError![
13083591
1309 const info = @as(*OBJECT_NAME_INFORMATION, @ptrCast(out_buffer_aligned));3592 const info = @as(*OBJECT_NAME_INFORMATION, @ptrCast(out_buffer_aligned));
1310 // buffer size is specified in bytes3593 // buffer size is specified in bytes
1311 const out_buffer_len = std.math.cast(ULONG, out_buffer_aligned.len * 2) orelse std.math.maxInt(ULONG);3594 const out_buffer_len = std.math.cast(ULONG, out_buffer_aligned.len * 2) orelse maxInt(ULONG);
1312 // last argument would return the length required for full_buffer, not exposed here3595 // last argument would return the length required for full_buffer, not exposed here
1313 return switch (ntdll.NtQueryObject(handle, .ObjectNameInformation, info, out_buffer_len, null)) {3596 return switch (ntdll.NtQueryObject(handle, .ObjectNameInformation, info, out_buffer_len, null)) {
1314 .SUCCESS => blk: {3597 .SUCCESS => blk: {
...@@ -1440,9 +3723,8 @@ pub fn GetFinalPathNameByHandle(...@@ -1440,9 +3723,8 @@ pub fn GetFinalPathNameByHandle(
1440 // This is the NT namespaced version of \\.\MountPointManager3723 // This is the NT namespaced version of \\.\MountPointManager
1441 const mgmt_path_u16 = std.unicode.utf8ToUtf16LeStringLiteral("\\??\\MountPointManager");3724 const mgmt_path_u16 = std.unicode.utf8ToUtf16LeStringLiteral("\\??\\MountPointManager");
1442 const mgmt_handle = OpenFile(mgmt_path_u16, .{3725 const mgmt_handle = OpenFile(mgmt_path_u16, .{
1443 .access_mask = SYNCHRONIZE,3726 .access_mask = .{ .STANDARD = .{ .SYNCHRONIZE = true } },
1444 .share_access = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,3727 .creation = .OPEN,
1445 .creation = FILE_OPEN,
1446 }) catch |err| switch (err) {3728 }) catch |err| switch (err) {
1447 error.IsDir => return error.Unexpected,3729 error.IsDir => return error.Unexpected,
1448 error.NotDir => return error.Unexpected,3730 error.NotDir => return error.Unexpected,
...@@ -1462,8 +3744,12 @@ pub fn GetFinalPathNameByHandle(...@@ -1462,8 +3744,12 @@ pub fn GetFinalPathNameByHandle(
1462 input_struct.DeviceNameLength = @intCast(volume_name_u16.len * 2);3744 input_struct.DeviceNameLength = @intCast(volume_name_u16.len * 2);
1463 @memcpy(input_buf[@sizeOf(MOUNTMGR_MOUNT_POINT)..][0 .. volume_name_u16.len * 2], @as([*]const u8, @ptrCast(volume_name_u16.ptr)));3745 @memcpy(input_buf[@sizeOf(MOUNTMGR_MOUNT_POINT)..][0 .. volume_name_u16.len * 2], @as([*]const u8, @ptrCast(volume_name_u16.ptr)));
14643746
1465 DeviceIoControl(mgmt_handle, IOCTL_MOUNTMGR_QUERY_POINTS, &input_buf, &output_buf) catch |err| switch (err) {3747 DeviceIoControl(mgmt_handle, IOCTL.MOUNTMGR.QUERY_POINTS, .{ .in = &input_buf, .out = &output_buf }) catch |err| switch (err) {
3748 error.PipeClosing => unreachable,
3749 error.PipeAlreadyConnected => unreachable,
3750 error.PipeAlreadyListening => unreachable,
1466 error.AccessDenied => return error.Unexpected,3751 error.AccessDenied => return error.Unexpected,
3752 error.Pending => unreachable,
1467 else => |e| return e,3753 else => |e| return e,
1468 };3754 };
1469 const mount_points_struct: *const MOUNTMGR_MOUNT_POINTS = @ptrCast(&output_buf[0]);3755 const mount_points_struct: *const MOUNTMGR_MOUNT_POINTS = @ptrCast(&output_buf[0]);
...@@ -1517,8 +3803,12 @@ pub fn GetFinalPathNameByHandle(...@@ -1517,8 +3803,12 @@ pub fn GetFinalPathNameByHandle(
1517 vol_input_struct.DeviceNameLength = @intCast(symlink.len * 2);3803 vol_input_struct.DeviceNameLength = @intCast(symlink.len * 2);
1518 @memcpy(@as([*]WCHAR, &vol_input_struct.DeviceName)[0..symlink.len], symlink);3804 @memcpy(@as([*]WCHAR, &vol_input_struct.DeviceName)[0..symlink.len], symlink);
15193805
1520 DeviceIoControl(mgmt_handle, IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH, &vol_input_buf, &vol_output_buf) catch |err| switch (err) {3806 DeviceIoControl(mgmt_handle, IOCTL.MOUNTMGR.QUERY_DOS_VOLUME_PATH, .{ .in = &vol_input_buf, .out = &vol_output_buf }) catch |err| switch (err) {
3807 error.PipeClosing => unreachable,
3808 error.PipeAlreadyConnected => unreachable,
3809 error.PipeAlreadyListening => unreachable,
1521 error.AccessDenied => return error.Unexpected,3810 error.AccessDenied => return error.Unexpected,
3811 error.Pending => unreachable,
1522 else => |e| return e,3812 else => |e| return e,
1523 };3813 };
1524 const volume_paths_struct: *const MOUNTMGR_VOLUME_PATHS = @ptrCast(&vol_output_buf[0]);3814 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...@@ -1758,7 +4048,7 @@ pub fn VirtualProtect(lpAddress: ?LPVOID, dwSize: SIZE_T, flNewProtect: DWORD, l
1758 // ntdll takes an extra level of indirection here4048 // ntdll takes an extra level of indirection here
1759 var addr = lpAddress;4049 var addr = lpAddress;
1760 var size = dwSize;4050 var size = dwSize;
1761 switch (ntdll.NtProtectVirtualMemory(self_process_handle, &addr, &size, flNewProtect, lpflOldProtect)) {4051 switch (ntdll.NtProtectVirtualMemory(GetCurrentProcess(), &addr, &size, flNewProtect, lpflOldProtect)) {
1762 .SUCCESS => {},4052 .SUCCESS => {},
1763 .INVALID_ADDRESS => return error.InvalidAddress,4053 .INVALID_ADDRESS => return error.InvalidAddress,
1764 else => |st| return unexpectedStatus(st),4054 else => |st| return unexpectedStatus(st),
...@@ -2018,7 +4308,7 @@ pub const LockFileError = error{...@@ -2018,7 +4308,7 @@ pub const LockFileError = error{
2018pub fn LockFile(4308pub fn LockFile(
2019 FileHandle: HANDLE,4309 FileHandle: HANDLE,
2020 Event: ?HANDLE,4310 Event: ?HANDLE,
2021 ApcRoutine: ?*IO_APC_ROUTINE,4311 ApcRoutine: ?*const IO_APC_ROUTINE,
2022 ApcContext: ?*anyopaque,4312 ApcContext: ?*anyopaque,
2023 IoStatusBlock: *IO_STATUS_BLOCK,4313 IoStatusBlock: *IO_STATUS_BLOCK,
2024 ByteOffset: *const LARGE_INTEGER,4314 ByteOffset: *const LARGE_INTEGER,
...@@ -2057,7 +4347,7 @@ pub fn UnlockFile(...@@ -2057,7 +4347,7 @@ pub fn UnlockFile(
2057 IoStatusBlock: *IO_STATUS_BLOCK,4347 IoStatusBlock: *IO_STATUS_BLOCK,
2058 ByteOffset: *const LARGE_INTEGER,4348 ByteOffset: *const LARGE_INTEGER,
2059 Length: *const LARGE_INTEGER,4349 Length: *const LARGE_INTEGER,
2060 Key: ?*ULONG,4350 Key: ULONG,
2061) !void {4351) !void {
2062 const rc = ntdll.NtUnlockFile(FileHandle, IoStatusBlock, ByteOffset, Length, Key);4352 const rc = ntdll.NtUnlockFile(FileHandle, IoStatusBlock, ByteOffset, Length, Key);
2063 switch (rc) {4353 switch (rc) {
...@@ -2168,13 +4458,13 @@ pub fn eqlIgnoreCaseWtf16(a: []const u16, b: []const u16) bool {...@@ -2168,13 +4458,13 @@ pub fn eqlIgnoreCaseWtf16(a: []const u16, b: []const u16) bool {
2168 // Use RtlEqualUnicodeString on Windows when not in comptime to avoid including a4458 // Use RtlEqualUnicodeString on Windows when not in comptime to avoid including a
2169 // redundant copy of the uppercase data.4459 // redundant copy of the uppercase data.
2170 const a_bytes = @as(u16, @intCast(a.len * 2));4460 const a_bytes = @as(u16, @intCast(a.len * 2));
2171 const a_string = UNICODE_STRING{4461 const a_string: UNICODE_STRING = .{
2172 .Length = a_bytes,4462 .Length = a_bytes,
2173 .MaximumLength = a_bytes,4463 .MaximumLength = a_bytes,
2174 .Buffer = @constCast(a.ptr),4464 .Buffer = @constCast(a.ptr),
2175 };4465 };
2176 const b_bytes = @as(u16, @intCast(b.len * 2));4466 const b_bytes = @as(u16, @intCast(b.len * 2));
2177 const b_string = UNICODE_STRING{4467 const b_string: UNICODE_STRING = .{
2178 .Length = b_bytes,4468 .Length = b_bytes,
2179 .MaximumLength = b_bytes,4469 .MaximumLength = b_bytes,
2180 .Buffer = @constCast(b.ptr),4470 .Buffer = @constCast(b.ptr),
...@@ -2206,7 +4496,7 @@ pub fn eqlIgnoreCaseWtf8(a: []const u8, b: []const u8) bool {...@@ -2206,7 +4496,7 @@ pub fn eqlIgnoreCaseWtf8(a: []const u8, b: []const u8) bool {
2206 const a_cp = a_wtf8_it.nextCodepoint() orelse break;4496 const a_cp = a_wtf8_it.nextCodepoint() orelse break;
2207 const b_cp = b_wtf8_it.nextCodepoint() orelse return false;4497 const b_cp = b_wtf8_it.nextCodepoint() orelse return false;
22084498
2209 if (a_cp <= std.math.maxInt(u16) and b_cp <= std.math.maxInt(u16)) {4499 if (a_cp <= maxInt(u16) and b_cp <= maxInt(u16)) {
2210 if (a_cp != b_cp and upcaseImpl(@intCast(a_cp)) != upcaseImpl(@intCast(b_cp))) {4500 if (a_cp != b_cp and upcaseImpl(@intCast(a_cp)) != upcaseImpl(@intCast(b_cp))) {
2211 return false;4501 return false;
2212 }4502 }
...@@ -2783,7 +5073,10 @@ pub fn unexpectedWSAError(err: ws2_32.WinsockError) UnexpectedError {...@@ -2783,7 +5073,10 @@ pub fn unexpectedWSAError(err: ws2_32.WinsockError) UnexpectedError {
2783/// and you get an unexpected status.5073/// and you get an unexpected status.
2784pub fn unexpectedStatus(status: NTSTATUS) UnexpectedError {5074pub fn unexpectedStatus(status: NTSTATUS) UnexpectedError {
2785 if (std.posix.unexpected_error_tracing) {5075 if (std.posix.unexpected_error_tracing) {
2786 std.debug.print("error.Unexpected NTSTATUS=0x{x}\n", .{@intFromEnum(status)});5076 std.debug.print("error.Unexpected NTSTATUS=0x{x} ({s})\n", .{
5077 @intFromEnum(status),
5078 std.enums.tagName(NTSTATUS, status) orelse "<unnamed>",
5079 });
2787 std.debug.dumpCurrentStackTrace(.{ .first_address = @returnAddress() });5080 std.debug.dumpCurrentStackTrace(.{ .first_address = @returnAddress() });
2788 }5081 }
2789 return error.Unexpected;5082 return error.Unexpected;
...@@ -2791,20 +5084,25 @@ pub fn unexpectedStatus(status: NTSTATUS) UnexpectedError {...@@ -2791,20 +5084,25 @@ pub fn unexpectedStatus(status: NTSTATUS) UnexpectedError {
27915084
2792pub fn statusBug(status: NTSTATUS) UnexpectedError {5085pub fn statusBug(status: NTSTATUS) UnexpectedError {
2793 switch (builtin.mode) {5086 switch (builtin.mode) {
2794 .Debug => std.debug.panic("programmer bug caused syscall status: {t}", .{status}),5087 .Debug => std.debug.panic("programmer bug caused syscall status: 0x{x} ({s})", .{
5088 @intFromEnum(status),
5089 std.enums.tagName(NTSTATUS, status) orelse "<unnamed>",
5090 }),
2795 else => return error.Unexpected,5091 else => return error.Unexpected,
2796 }5092 }
2797}5093}
27985094
2799pub fn errorBug(err: Win32Error) UnexpectedError {5095pub fn errorBug(err: Win32Error) UnexpectedError {
2800 switch (builtin.mode) {5096 switch (builtin.mode) {
2801 .Debug => std.debug.panic("programmer bug caused syscall status: {t}", .{err}),5097 .Debug => std.debug.panic("programmer bug caused syscall error: 0x{x} ({s})", .{
5098 @intFromEnum(err),
5099 std.enums.tagName(Win32Error, err) orelse "<unnamed>",
5100 }),
2802 else => return error.Unexpected,5101 else => return error.Unexpected,
2803 }5102 }
2804}5103}
28055104
2806pub const Win32Error = @import("windows/win32error.zig").Win32Error;5105pub const Win32Error = @import("windows/win32error.zig").Win32Error;
2807pub const NTSTATUS = @import("windows/ntstatus.zig").NTSTATUS;
2808pub const LANG = @import("windows/lang.zig");5106pub const LANG = @import("windows/lang.zig");
2809pub const SUBLANG = @import("windows/sublang.zig");5107pub const SUBLANG = @import("windows/sublang.zig");
28105108
...@@ -2885,217 +5183,9 @@ pub const PCTSTR = @compileError("Deprecated: choose between `PCSTR` or `PCWSTR`...@@ -2885,217 +5183,9 @@ pub const PCTSTR = @compileError("Deprecated: choose between `PCSTR` or `PCWSTR`
2885pub const TRUE = 1;5183pub const TRUE = 1;
2886pub const FALSE = 0;5184pub const FALSE = 0;
28875185
2888pub const DEVICE_TYPE = ULONG;5186pub const INVALID_HANDLE_VALUE: HANDLE = @ptrFromInt(maxInt(usize));
2889pub const FILE_DEVICE_BEEP: DEVICE_TYPE = 0x0001;
2890pub const FILE_DEVICE_CD_ROM: DEVICE_TYPE = 0x0002;
2891pub const FILE_DEVICE_CD_ROM_FILE_SYSTEM: DEVICE_TYPE = 0x0003;
2892pub const FILE_DEVICE_CONTROLLER: DEVICE_TYPE = 0x0004;
2893pub const FILE_DEVICE_DATALINK: DEVICE_TYPE = 0x0005;
2894pub const FILE_DEVICE_DFS: DEVICE_TYPE = 0x0006;
2895pub const FILE_DEVICE_DISK: DEVICE_TYPE = 0x0007;
2896pub const FILE_DEVICE_DISK_FILE_SYSTEM: DEVICE_TYPE = 0x0008;
2897pub const FILE_DEVICE_FILE_SYSTEM: DEVICE_TYPE = 0x0009;
2898pub const FILE_DEVICE_INPORT_PORT: DEVICE_TYPE = 0x000a;
2899pub const FILE_DEVICE_KEYBOARD: DEVICE_TYPE = 0x000b;
2900pub const FILE_DEVICE_MAILSLOT: DEVICE_TYPE = 0x000c;
2901pub const FILE_DEVICE_MIDI_IN: DEVICE_TYPE = 0x000d;
2902pub const FILE_DEVICE_MIDI_OUT: DEVICE_TYPE = 0x000e;
2903pub const FILE_DEVICE_MOUSE: DEVICE_TYPE = 0x000f;
2904pub const FILE_DEVICE_MULTI_UNC_PROVIDER: DEVICE_TYPE = 0x0010;
2905pub const FILE_DEVICE_NAMED_PIPE: DEVICE_TYPE = 0x0011;
2906pub const FILE_DEVICE_NETWORK: DEVICE_TYPE = 0x0012;
2907pub const FILE_DEVICE_NETWORK_BROWSER: DEVICE_TYPE = 0x0013;
2908pub const FILE_DEVICE_NETWORK_FILE_SYSTEM: DEVICE_TYPE = 0x0014;
2909pub const FILE_DEVICE_NULL: DEVICE_TYPE = 0x0015;
2910pub const FILE_DEVICE_PARALLEL_PORT: DEVICE_TYPE = 0x0016;
2911pub const FILE_DEVICE_PHYSICAL_NETCARD: DEVICE_TYPE = 0x0017;
2912pub const FILE_DEVICE_PRINTER: DEVICE_TYPE = 0x0018;
2913pub const FILE_DEVICE_SCANNER: DEVICE_TYPE = 0x0019;
2914pub const FILE_DEVICE_SERIAL_MOUSE_PORT: DEVICE_TYPE = 0x001a;
2915pub const FILE_DEVICE_SERIAL_PORT: DEVICE_TYPE = 0x001b;
2916pub const FILE_DEVICE_SCREEN: DEVICE_TYPE = 0x001c;
2917pub const FILE_DEVICE_SOUND: DEVICE_TYPE = 0x001d;
2918pub const FILE_DEVICE_STREAMS: DEVICE_TYPE = 0x001e;
2919pub const FILE_DEVICE_TAPE: DEVICE_TYPE = 0x001f;
2920pub const FILE_DEVICE_TAPE_FILE_SYSTEM: DEVICE_TYPE = 0x0020;
2921pub const FILE_DEVICE_TRANSPORT: DEVICE_TYPE = 0x0021;
2922pub const FILE_DEVICE_UNKNOWN: DEVICE_TYPE = 0x0022;
2923pub const FILE_DEVICE_VIDEO: DEVICE_TYPE = 0x0023;
2924pub const FILE_DEVICE_VIRTUAL_DISK: DEVICE_TYPE = 0x0024;
2925pub const FILE_DEVICE_WAVE_IN: DEVICE_TYPE = 0x0025;
2926pub const FILE_DEVICE_WAVE_OUT: DEVICE_TYPE = 0x0026;
2927pub const FILE_DEVICE_8042_PORT: DEVICE_TYPE = 0x0027;
2928pub const FILE_DEVICE_NETWORK_REDIRECTOR: DEVICE_TYPE = 0x0028;
2929pub const FILE_DEVICE_BATTERY: DEVICE_TYPE = 0x0029;
2930pub const FILE_DEVICE_BUS_EXTENDER: DEVICE_TYPE = 0x002a;
2931pub const FILE_DEVICE_MODEM: DEVICE_TYPE = 0x002b;
2932pub const FILE_DEVICE_VDM: DEVICE_TYPE = 0x002c;
2933pub const FILE_DEVICE_MASS_STORAGE: DEVICE_TYPE = 0x002d;
2934pub const FILE_DEVICE_SMB: DEVICE_TYPE = 0x002e;
2935pub const FILE_DEVICE_KS: DEVICE_TYPE = 0x002f;
2936pub const FILE_DEVICE_CHANGER: DEVICE_TYPE = 0x0030;
2937pub const FILE_DEVICE_SMARTCARD: DEVICE_TYPE = 0x0031;
2938pub const FILE_DEVICE_ACPI: DEVICE_TYPE = 0x0032;
2939pub const FILE_DEVICE_DVD: DEVICE_TYPE = 0x0033;
2940pub const FILE_DEVICE_FULLSCREEN_VIDEO: DEVICE_TYPE = 0x0034;
2941pub const FILE_DEVICE_DFS_FILE_SYSTEM: DEVICE_TYPE = 0x0035;
2942pub const FILE_DEVICE_DFS_VOLUME: DEVICE_TYPE = 0x0036;
2943pub const FILE_DEVICE_SERENUM: DEVICE_TYPE = 0x0037;
2944pub const FILE_DEVICE_TERMSRV: DEVICE_TYPE = 0x0038;
2945pub const FILE_DEVICE_KSEC: DEVICE_TYPE = 0x0039;
2946pub const FILE_DEVICE_FIPS: DEVICE_TYPE = 0x003a;
2947pub const FILE_DEVICE_INFINIBAND: DEVICE_TYPE = 0x003b;
2948// TODO: missing values?
2949pub const FILE_DEVICE_VMBUS: DEVICE_TYPE = 0x003e;
2950pub const FILE_DEVICE_CRYPT_PROVIDER: DEVICE_TYPE = 0x003f;
2951pub const FILE_DEVICE_WPD: DEVICE_TYPE = 0x0040;
2952pub const FILE_DEVICE_BLUETOOTH: DEVICE_TYPE = 0x0041;
2953pub const FILE_DEVICE_MT_COMPOSITE: DEVICE_TYPE = 0x0042;
2954pub const FILE_DEVICE_MT_TRANSPORT: DEVICE_TYPE = 0x0043;
2955pub const FILE_DEVICE_BIOMETRIC: DEVICE_TYPE = 0x0044;
2956pub const FILE_DEVICE_PMI: DEVICE_TYPE = 0x0045;
2957pub const FILE_DEVICE_EHSTOR: DEVICE_TYPE = 0x0046;
2958pub const FILE_DEVICE_DEVAPI: DEVICE_TYPE = 0x0047;
2959pub const FILE_DEVICE_GPIO: DEVICE_TYPE = 0x0048;
2960pub const FILE_DEVICE_USBEX: DEVICE_TYPE = 0x0049;
2961pub const FILE_DEVICE_CONSOLE: DEVICE_TYPE = 0x0050;
2962pub const FILE_DEVICE_NFP: DEVICE_TYPE = 0x0051;
2963pub const FILE_DEVICE_SYSENV: DEVICE_TYPE = 0x0052;
2964pub const FILE_DEVICE_VIRTUAL_BLOCK: DEVICE_TYPE = 0x0053;
2965pub const FILE_DEVICE_POINT_OF_SERVICE: DEVICE_TYPE = 0x0054;
2966pub const FILE_DEVICE_STORAGE_REPLICATION: DEVICE_TYPE = 0x0055;
2967pub const FILE_DEVICE_TRUST_ENV: DEVICE_TYPE = 0x0056;
2968pub const FILE_DEVICE_UCM: DEVICE_TYPE = 0x0057;
2969pub const FILE_DEVICE_UCMTCPCI: DEVICE_TYPE = 0x0058;
2970pub const FILE_DEVICE_PERSISTENT_MEMORY: DEVICE_TYPE = 0x0059;
2971pub const FILE_DEVICE_NVDIMM: DEVICE_TYPE = 0x005a;
2972pub const FILE_DEVICE_HOLOGRAPHIC: DEVICE_TYPE = 0x005b;
2973pub const FILE_DEVICE_SDFXHCI: DEVICE_TYPE = 0x005c;
2974
2975/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/buffer-descriptions-for-i-o-control-codes
2976pub const TransferType = enum(u2) {
2977 METHOD_BUFFERED = 0,
2978 METHOD_IN_DIRECT = 1,
2979 METHOD_OUT_DIRECT = 2,
2980 METHOD_NEITHER = 3,
2981};
2982
2983pub const FILE_ANY_ACCESS = 0;
2984pub const FILE_READ_ACCESS = 1;
2985pub const FILE_WRITE_ACCESS = 2;
2986
2987/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes
2988pub fn CTL_CODE(deviceType: u16, function: u12, method: TransferType, access: u2) DWORD {
2989 return (@as(DWORD, deviceType) << 16) |
2990 (@as(DWORD, access) << 14) |
2991 (@as(DWORD, function) << 2) |
2992 @intFromEnum(method);
2993}
2994
2995pub const INVALID_HANDLE_VALUE = @as(HANDLE, @ptrFromInt(maxInt(usize)));
2996
2997pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD));
2998
2999pub const FILE_ALL_INFORMATION = extern struct {
3000 BasicInformation: FILE_BASIC_INFORMATION,
3001 StandardInformation: FILE_STANDARD_INFORMATION,
3002 InternalInformation: FILE_INTERNAL_INFORMATION,
3003 EaInformation: FILE_EA_INFORMATION,
3004 AccessInformation: FILE_ACCESS_INFORMATION,
3005 PositionInformation: FILE_POSITION_INFORMATION,
3006 ModeInformation: FILE_MODE_INFORMATION,
3007 AlignmentInformation: FILE_ALIGNMENT_INFORMATION,
3008 NameInformation: FILE_NAME_INFORMATION,
3009};
3010
3011pub const FILE_BASIC_INFORMATION = extern struct {
3012 CreationTime: LARGE_INTEGER,
3013 LastAccessTime: LARGE_INTEGER,
3014 LastWriteTime: LARGE_INTEGER,
3015 ChangeTime: LARGE_INTEGER,
3016 FileAttributes: ULONG,
3017};
3018
3019pub const FILE_STANDARD_INFORMATION = extern struct {
3020 AllocationSize: LARGE_INTEGER,
3021 EndOfFile: LARGE_INTEGER,
3022 NumberOfLinks: ULONG,
3023 DeletePending: BOOLEAN,
3024 Directory: BOOLEAN,
3025};
3026
3027pub const FILE_INTERNAL_INFORMATION = extern struct {
3028 IndexNumber: LARGE_INTEGER,
3029};
3030
3031pub const FILE_EA_INFORMATION = extern struct {
3032 EaSize: ULONG,
3033};
3034
3035pub const FILE_ACCESS_INFORMATION = extern struct {
3036 AccessFlags: ACCESS_MASK,
3037};
3038
3039pub const FILE_POSITION_INFORMATION = extern struct {
3040 CurrentByteOffset: LARGE_INTEGER,
3041};
3042
3043pub const FILE_END_OF_FILE_INFORMATION = extern struct {
3044 EndOfFile: LARGE_INTEGER,
3045};
3046
3047pub const FILE_MODE_INFORMATION = extern struct {
3048 Mode: ULONG,
3049};
3050
3051pub const FILE_ALIGNMENT_INFORMATION = extern struct {
3052 AlignmentRequirement: ULONG,
3053};
3054
3055pub const FILE_NAME_INFORMATION = extern struct {
3056 FileNameLength: ULONG,
3057 FileName: [1]WCHAR,
3058};
3059
3060pub const FILE_DISPOSITION_INFORMATION_EX = extern struct {
3061 /// combination of FILE_DISPOSITION_* flags
3062 Flags: ULONG,
3063};
3064
3065pub const FILE_DISPOSITION_DO_NOT_DELETE: ULONG = 0x00000000;
3066pub const FILE_DISPOSITION_DELETE: ULONG = 0x00000001;
3067pub const FILE_DISPOSITION_POSIX_SEMANTICS: ULONG = 0x00000002;
3068pub const FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK: ULONG = 0x00000004;
3069pub const FILE_DISPOSITION_ON_CLOSE: ULONG = 0x00000008;
3070pub const FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE: ULONG = 0x00000010;
3071
3072// FILE_RENAME_INFORMATION.Flags
3073pub const FILE_RENAME_REPLACE_IF_EXISTS = 0x00000001;
3074pub const FILE_RENAME_POSIX_SEMANTICS = 0x00000002;
3075pub const FILE_RENAME_SUPPRESS_PIN_STATE_INHERITANCE = 0x00000004;
3076pub const FILE_RENAME_SUPPRESS_STORAGE_RESERVE_INHERITANCE = 0x00000008;
3077pub const FILE_RENAME_NO_INCREASE_AVAILABLE_SPACE = 0x00000010;
3078pub const FILE_RENAME_NO_DECREASE_AVAILABLE_SPACE = 0x00000020;
3079pub const FILE_RENAME_PRESERVE_AVAILABLE_SPACE = 0x00000030;
3080pub const FILE_RENAME_IGNORE_READONLY_ATTRIBUTE = 0x00000040;
3081pub const FILE_RENAME_FORCE_RESIZE_TARGET_SR = 0x00000080;
3082pub const FILE_RENAME_FORCE_RESIZE_SOURCE_SR = 0x00000100;
3083pub const FILE_RENAME_FORCE_RESIZE_SR = 0x00000180;
3084
3085pub const FILE_RENAME_INFORMATION = extern struct {
3086 Flags: BOOLEAN,
3087 RootDirectory: ?HANDLE,
3088 FileNameLength: ULONG,
3089 FileName: [1]WCHAR,
3090};
30915187
3092// FileRenameInformationEx (since .win10_rs1)5188pub const INVALID_FILE_ATTRIBUTES: DWORD = maxInt(DWORD);
3093pub const FILE_RENAME_INFORMATION_EX = extern struct {
3094 Flags: ULONG,
3095 RootDirectory: ?HANDLE,
3096 FileNameLength: ULONG,
3097 FileName: [1]WCHAR,
3098};
30995189
3100pub const IO_STATUS_BLOCK = extern struct {5190pub const IO_STATUS_BLOCK = extern struct {
3101 // "DUMMYUNIONNAME" expands to "u"5191 // "DUMMYUNIONNAME" expands to "u"
...@@ -3106,130 +5196,6 @@ pub const IO_STATUS_BLOCK = extern struct {...@@ -3106,130 +5196,6 @@ pub const IO_STATUS_BLOCK = extern struct {
3106 Information: ULONG_PTR,5196 Information: ULONG_PTR,
3107};5197};
31085198
3109pub const FILE_INFORMATION_CLASS = enum(c_int) {
3110 FileDirectoryInformation = 1,
3111 FileFullDirectoryInformation,
3112 FileBothDirectoryInformation,
3113 FileBasicInformation,
3114 FileStandardInformation,
3115 FileInternalInformation,
3116 FileEaInformation,
3117 FileAccessInformation,
3118 FileNameInformation,
3119 FileRenameInformation,
3120 FileLinkInformation,
3121 FileNamesInformation,
3122 FileDispositionInformation,
3123 FilePositionInformation,
3124 FileFullEaInformation,
3125 FileModeInformation,
3126 FileAlignmentInformation,
3127 FileAllInformation,
3128 FileAllocationInformation,
3129 FileEndOfFileInformation,
3130 FileAlternateNameInformation,
3131 FileStreamInformation,
3132 FilePipeInformation,
3133 FilePipeLocalInformation,
3134 FilePipeRemoteInformation,
3135 FileMailslotQueryInformation,
3136 FileMailslotSetInformation,
3137 FileCompressionInformation,
3138 FileObjectIdInformation,
3139 FileCompletionInformation,
3140 FileMoveClusterInformation,
3141 FileQuotaInformation,
3142 FileReparsePointInformation,
3143 FileNetworkOpenInformation,
3144 FileAttributeTagInformation,
3145 FileTrackingInformation,
3146 FileIdBothDirectoryInformation,
3147 FileIdFullDirectoryInformation,
3148 FileValidDataLengthInformation,
3149 FileShortNameInformation,
3150 FileIoCompletionNotificationInformation,
3151 FileIoStatusBlockRangeInformation,
3152 FileIoPriorityHintInformation,
3153 FileSfioReserveInformation,
3154 FileSfioVolumeInformation,
3155 FileHardLinkInformation,
3156 FileProcessIdsUsingFileInformation,
3157 FileNormalizedNameInformation,
3158 FileNetworkPhysicalNameInformation,
3159 FileIdGlobalTxDirectoryInformation,
3160 FileIsRemoteDeviceInformation,
3161 FileUnusedInformation,
3162 FileNumaNodeInformation,
3163 FileStandardLinkInformation,
3164 FileRemoteProtocolInformation,
3165 FileRenameInformationBypassAccessCheck,
3166 FileLinkInformationBypassAccessCheck,
3167 FileVolumeNameInformation,
3168 FileIdInformation,
3169 FileIdExtdDirectoryInformation,
3170 FileReplaceCompletionInformation,
3171 FileHardLinkFullIdInformation,
3172 FileIdExtdBothDirectoryInformation,
3173 FileDispositionInformationEx,
3174 FileRenameInformationEx,
3175 FileRenameInformationExBypassAccessCheck,
3176 FileDesiredStorageClassInformation,
3177 FileStatInformation,
3178 FileMemoryPartitionInformation,
3179 FileStatLxInformation,
3180 FileCaseSensitiveInformation,
3181 FileLinkInformationEx,
3182 FileLinkInformationExBypassAccessCheck,
3183 FileStorageReserveIdInformation,
3184 FileCaseSensitiveInformationForceAccessCheck,
3185 FileMaximumInformation,
3186};
3187
3188pub const FILE_ATTRIBUTE_TAG_INFO = extern struct {
3189 FileAttributes: DWORD,
3190 ReparseTag: DWORD,
3191};
3192
3193/// "If this bit is set, the file or directory represents another named entity in the system."
3194/// https://learn.microsoft.com/en-us/windows/win32/fileio/reparse-point-tags
3195pub const reparse_tag_name_surrogate_bit = 0x20000000;
3196
3197pub const FILE_DISPOSITION_INFORMATION = extern struct {
3198 DeleteFile: BOOLEAN,
3199};
3200
3201pub const FILE_FS_DEVICE_INFORMATION = extern struct {
3202 DeviceType: DEVICE_TYPE,
3203 Characteristics: ULONG,
3204};
3205
3206pub const FILE_FS_VOLUME_INFORMATION = extern struct {
3207 VolumeCreationTime: LARGE_INTEGER,
3208 VolumeSerialNumber: ULONG,
3209 VolumeLabelLength: ULONG,
3210 SupportsObjects: BOOLEAN,
3211 // Flexible array member
3212 VolumeLabel: [1]WCHAR,
3213};
3214
3215pub const FS_INFORMATION_CLASS = enum(c_int) {
3216 FileFsVolumeInformation = 1,
3217 FileFsLabelInformation,
3218 FileFsSizeInformation,
3219 FileFsDeviceInformation,
3220 FileFsAttributeInformation,
3221 FileFsControlInformation,
3222 FileFsFullSizeInformation,
3223 FileFsObjectIdInformation,
3224 FileFsDriverPathInformation,
3225 FileFsVolumeFlagsInformation,
3226 FileFsSectorSizeInformation,
3227 FileFsDataCopyInformation,
3228 FileFsMetadataSizeInformation,
3229 FileFsFullSizeInformationEx,
3230 FileFsMaximumInformation,
3231};
3232
3233pub const OVERLAPPED = extern struct {5199pub const OVERLAPPED = extern struct {
3234 Internal: ULONG_PTR,5200 Internal: ULONG_PTR,
3235 InternalHigh: ULONG_PTR,5201 InternalHigh: ULONG_PTR,
...@@ -3331,129 +5297,16 @@ pub const PIPE_READMODE_MESSAGE = 0x00000002;...@@ -3331,129 +5297,16 @@ pub const PIPE_READMODE_MESSAGE = 0x00000002;
3331pub const PIPE_WAIT = 0x00000000;5297pub const PIPE_WAIT = 0x00000000;
3332pub const PIPE_NOWAIT = 0x00000001;5298pub const PIPE_NOWAIT = 0x00000001;
33335299
3334pub const GENERIC_READ = 0x80000000;
3335pub const GENERIC_WRITE = 0x40000000;
3336pub const GENERIC_EXECUTE = 0x20000000;
3337pub const GENERIC_ALL = 0x10000000;
3338
3339pub const FILE_SHARE_DELETE = 0x00000004;
3340pub const FILE_SHARE_READ = 0x00000001;
3341pub const FILE_SHARE_WRITE = 0x00000002;
3342
3343pub const DELETE = 0x00010000;
3344pub const READ_CONTROL = 0x00020000;
3345pub const WRITE_DAC = 0x00040000;
3346pub const WRITE_OWNER = 0x00080000;
3347pub const SYNCHRONIZE = 0x00100000;
3348pub const STANDARD_RIGHTS_READ = READ_CONTROL;
3349pub const STANDARD_RIGHTS_WRITE = READ_CONTROL;
3350pub const STANDARD_RIGHTS_EXECUTE = READ_CONTROL;
3351pub const STANDARD_RIGHTS_REQUIRED = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER;
3352pub const MAXIMUM_ALLOWED = 0x02000000;
3353
3354// disposition for NtCreateFile
3355pub const FILE_SUPERSEDE = 0;
3356pub const FILE_OPEN = 1;
3357pub const FILE_CREATE = 2;
3358pub const FILE_OPEN_IF = 3;
3359pub const FILE_OVERWRITE = 4;
3360pub const FILE_OVERWRITE_IF = 5;
3361pub const FILE_MAXIMUM_DISPOSITION = 5;
3362
3363// flags for NtCreateFile and NtOpenFile
3364pub const FILE_READ_DATA = 0x00000001;
3365pub const FILE_LIST_DIRECTORY = 0x00000001;
3366pub const FILE_WRITE_DATA = 0x00000002;
3367pub const FILE_ADD_FILE = 0x00000002;
3368pub const FILE_APPEND_DATA = 0x00000004;
3369pub const FILE_ADD_SUBDIRECTORY = 0x00000004;
3370pub const FILE_CREATE_PIPE_INSTANCE = 0x00000004;
3371pub const FILE_READ_EA = 0x00000008;
3372pub const FILE_WRITE_EA = 0x00000010;
3373pub const FILE_EXECUTE = 0x00000020;
3374pub const FILE_TRAVERSE = 0x00000020;
3375pub const FILE_DELETE_CHILD = 0x00000040;
3376pub const FILE_READ_ATTRIBUTES = 0x00000080;
3377pub const FILE_WRITE_ATTRIBUTES = 0x00000100;
3378
3379pub const FILE_DIRECTORY_FILE = 0x00000001;
3380pub const FILE_WRITE_THROUGH = 0x00000002;
3381pub const FILE_SEQUENTIAL_ONLY = 0x00000004;
3382pub const FILE_NO_INTERMEDIATE_BUFFERING = 0x00000008;
3383pub const FILE_SYNCHRONOUS_IO_ALERT = 0x00000010;
3384pub const FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020;
3385pub const FILE_NON_DIRECTORY_FILE = 0x00000040;
3386pub const FILE_CREATE_TREE_CONNECTION = 0x00000080;
3387pub const FILE_COMPLETE_IF_OPLOCKED = 0x00000100;
3388pub const FILE_NO_EA_KNOWLEDGE = 0x00000200;
3389pub const FILE_OPEN_FOR_RECOVERY = 0x00000400;
3390pub const FILE_RANDOM_ACCESS = 0x00000800;
3391pub const FILE_DELETE_ON_CLOSE = 0x00001000;
3392pub const FILE_OPEN_BY_FILE_ID = 0x00002000;
3393pub const FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000;
3394pub const FILE_NO_COMPRESSION = 0x00008000;
3395pub const FILE_RESERVE_OPFILTER = 0x00100000;
3396pub const FILE_OPEN_REPARSE_POINT = 0x00200000;
3397pub const FILE_OPEN_OFFLINE_FILE = 0x00400000;
3398pub const FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000;
3399
3400pub const CREATE_ALWAYS = 2;5300pub const CREATE_ALWAYS = 2;
3401pub const CREATE_NEW = 1;5301pub const CREATE_NEW = 1;
3402pub const OPEN_ALWAYS = 4;5302pub const OPEN_ALWAYS = 4;
3403pub const OPEN_EXISTING = 3;5303pub const OPEN_EXISTING = 3;
3404pub const TRUNCATE_EXISTING = 5;5304pub const TRUNCATE_EXISTING = 5;
34055305
3406pub const FILE_ATTRIBUTE_ARCHIVE = 0x20;
3407pub const FILE_ATTRIBUTE_COMPRESSED = 0x800;
3408pub const FILE_ATTRIBUTE_DEVICE = 0x40;
3409pub const FILE_ATTRIBUTE_DIRECTORY = 0x10;
3410pub const FILE_ATTRIBUTE_ENCRYPTED = 0x4000;
3411pub const FILE_ATTRIBUTE_HIDDEN = 0x2;
3412pub const FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x8000;
3413pub const FILE_ATTRIBUTE_NORMAL = 0x80;
3414pub const FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000;
3415pub const FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x20000;
3416pub const FILE_ATTRIBUTE_OFFLINE = 0x1000;
3417pub const FILE_ATTRIBUTE_READONLY = 0x1;
3418pub const FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS = 0x400000;
3419pub const FILE_ATTRIBUTE_RECALL_ON_OPEN = 0x40000;
3420pub const FILE_ATTRIBUTE_REPARSE_POINT = 0x400;
3421pub const FILE_ATTRIBUTE_SPARSE_FILE = 0x200;
3422pub const FILE_ATTRIBUTE_SYSTEM = 0x4;
3423pub const FILE_ATTRIBUTE_TEMPORARY = 0x100;
3424pub const FILE_ATTRIBUTE_VIRTUAL = 0x10000;
3425
3426pub const FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1ff;
3427pub const FILE_GENERIC_READ = STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE;
3428pub const FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE;
3429pub const FILE_GENERIC_EXECUTE = STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE;
3430
3431// Flags for NtCreateNamedPipeFile
3432// NamedPipeType
3433pub const FILE_PIPE_BYTE_STREAM_TYPE = 0x0;
3434pub const FILE_PIPE_MESSAGE_TYPE = 0x1;
3435pub const FILE_PIPE_ACCEPT_REMOTE_CLIENTS = 0x0;
3436pub const FILE_PIPE_REJECT_REMOTE_CLIENTS = 0x2;
3437pub const FILE_PIPE_TYPE_VALID_MASK = 0x3;
3438// CompletionMode
3439pub const FILE_PIPE_QUEUE_OPERATION = 0x0;
3440pub const FILE_PIPE_COMPLETE_OPERATION = 0x1;
3441// ReadMode
3442pub const FILE_PIPE_BYTE_STREAM_MODE = 0x0;
3443pub const FILE_PIPE_MESSAGE_MODE = 0x1;
3444
3445// flags for CreateEvent5306// flags for CreateEvent
3446pub const CREATE_EVENT_INITIAL_SET = 0x00000002;5307pub const CREATE_EVENT_INITIAL_SET = 0x00000002;
3447pub const CREATE_EVENT_MANUAL_RESET = 0x00000001;5308pub const CREATE_EVENT_MANUAL_RESET = 0x00000001;
34485309
3449pub const EVENT_ALL_ACCESS = 0x1F0003;
3450pub const EVENT_MODIFY_STATE = 0x0002;
3451
3452// MEMORY_BASIC_INFORMATION.Type flags for VirtualQuery
3453pub const MEM_IMAGE = 0x1000000;
3454pub const MEM_MAPPED = 0x40000;
3455pub const MEM_PRIVATE = 0x20000;
3456
3457pub const PROCESS_INFORMATION = extern struct {5310pub const PROCESS_INFORMATION = extern struct {
3458 hProcess: HANDLE,5311 hProcess: HANDLE,
3459 hThread: HANDLE,5312 hThread: HANDLE,
...@@ -3521,45 +5374,6 @@ pub const FILE_BEGIN = 0;...@@ -3521,45 +5374,6 @@ pub const FILE_BEGIN = 0;
3521pub const FILE_CURRENT = 1;5374pub const FILE_CURRENT = 1;
3522pub const FILE_END = 2;5375pub const FILE_END = 2;
35235376
3524pub const HEAP_CREATE_ENABLE_EXECUTE = 0x00040000;
3525pub const HEAP_REALLOC_IN_PLACE_ONLY = 0x00000010;
3526pub const HEAP_GENERATE_EXCEPTIONS = 0x00000004;
3527pub const HEAP_NO_SERIALIZE = 0x00000001;
3528
3529// AllocationType values
3530pub const MEM_COMMIT = 0x1000;
3531pub const MEM_RESERVE = 0x2000;
3532pub const MEM_FREE = 0x10000;
3533pub const MEM_RESET = 0x80000;
3534pub const MEM_RESET_UNDO = 0x1000000;
3535pub const MEM_LARGE_PAGES = 0x20000000;
3536pub const MEM_PHYSICAL = 0x400000;
3537pub const MEM_TOP_DOWN = 0x100000;
3538pub const MEM_WRITE_WATCH = 0x200000;
3539pub const MEM_RESERVE_PLACEHOLDER = 0x00040000;
3540pub const MEM_PRESERVE_PLACEHOLDER = 0x00000400;
3541
3542// Protect values
3543pub const PAGE_EXECUTE = 0x10;
3544pub const PAGE_EXECUTE_READ = 0x20;
3545pub const PAGE_EXECUTE_READWRITE = 0x40;
3546pub const PAGE_EXECUTE_WRITECOPY = 0x80;
3547pub const PAGE_NOACCESS = 0x01;
3548pub const PAGE_READONLY = 0x02;
3549pub const PAGE_READWRITE = 0x04;
3550pub const PAGE_WRITECOPY = 0x08;
3551pub const PAGE_TARGETS_INVALID = 0x40000000;
3552pub const PAGE_TARGETS_NO_UPDATE = 0x40000000; // Same as PAGE_TARGETS_INVALID
3553pub const PAGE_GUARD = 0x100;
3554pub const PAGE_NOCACHE = 0x200;
3555pub const PAGE_WRITECOMBINE = 0x400;
3556
3557// FreeType values
3558pub const MEM_COALESCE_PLACEHOLDERS = 0x1;
3559pub const MEM_RESERVE_PLACEHOLDERS = 0x2;
3560pub const MEM_DECOMMIT = 0x4000;
3561pub const MEM_RELEASE = 0x8000;
3562
3563pub const PTHREAD_START_ROUTINE = *const fn (LPVOID) callconv(.winapi) DWORD;5377pub const PTHREAD_START_ROUTINE = *const fn (LPVOID) callconv(.winapi) DWORD;
3564pub const LPTHREAD_START_ROUTINE = PTHREAD_START_ROUTINE;5378pub const LPTHREAD_START_ROUTINE = PTHREAD_START_ROUTINE;
35655379
...@@ -3743,38 +5557,8 @@ pub const PIMAGE_TLS_CALLBACK = ?*const fn (PVOID, DWORD, PVOID) callconv(.winap...@@ -3743,38 +5557,8 @@ pub const PIMAGE_TLS_CALLBACK = ?*const fn (PVOID, DWORD, PVOID) callconv(.winap
3743pub const PROV_RSA_FULL = 1;5557pub const PROV_RSA_FULL = 1;
37445558
3745pub const REGSAM = ACCESS_MASK;5559pub const REGSAM = ACCESS_MASK;
3746pub const ACCESS_MASK = DWORD;
3747pub const LSTATUS = LONG;5560pub const LSTATUS = LONG;
37485561
3749pub const SECTION_INHERIT = enum(c_int) {
3750 ViewShare = 0,
3751 ViewUnmap = 1,
3752};
3753
3754pub const SECTION_QUERY = 0x0001;
3755pub const SECTION_MAP_WRITE = 0x0002;
3756pub const SECTION_MAP_READ = 0x0004;
3757pub const SECTION_MAP_EXECUTE = 0x0008;
3758pub const SECTION_EXTEND_SIZE = 0x0010;
3759pub const SECTION_ALL_ACCESS =
3760 STANDARD_RIGHTS_REQUIRED |
3761 SECTION_QUERY |
3762 SECTION_MAP_WRITE |
3763 SECTION_MAP_READ |
3764 SECTION_MAP_EXECUTE |
3765 SECTION_EXTEND_SIZE;
3766
3767pub const SEC_64K_PAGES = 0x80000;
3768pub const SEC_FILE = 0x800000;
3769pub const SEC_IMAGE = 0x1000000;
3770pub const SEC_PROTECTED_IMAGE = 0x2000000;
3771pub const SEC_RESERVE = 0x4000000;
3772pub const SEC_COMMIT = 0x8000000;
3773pub const SEC_IMAGE_NO_EXECUTE = SEC_IMAGE | SEC_NOCACHE;
3774pub const SEC_NOCACHE = 0x10000000;
3775pub const SEC_WRITECOMBINE = 0x40000000;
3776pub const SEC_LARGE_PAGES = 0x80000000;
3777
3778pub const HKEY = *opaque {};5562pub const HKEY = *opaque {};
37795563
3780pub const HKEY_CLASSES_ROOT: HKEY = @ptrFromInt(0x80000000);5564pub const HKEY_CLASSES_ROOT: HKEY = @ptrFromInt(0x80000000);
...@@ -3788,34 +5572,6 @@ pub const HKEY_CURRENT_CONFIG: HKEY = @ptrFromInt(0x80000005);...@@ -3788,34 +5572,6 @@ pub const HKEY_CURRENT_CONFIG: HKEY = @ptrFromInt(0x80000005);
3788pub const HKEY_DYN_DATA: HKEY = @ptrFromInt(0x80000006);5572pub const HKEY_DYN_DATA: HKEY = @ptrFromInt(0x80000006);
3789pub const HKEY_CURRENT_USER_LOCAL_SETTINGS: HKEY = @ptrFromInt(0x80000007);5573pub const HKEY_CURRENT_USER_LOCAL_SETTINGS: HKEY = @ptrFromInt(0x80000007);
37905574
3791/// Combines the STANDARD_RIGHTS_REQUIRED, KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY,
3792/// KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, and KEY_CREATE_LINK access rights.
3793pub const KEY_ALL_ACCESS = 0xF003F;
3794/// Reserved for system use.
3795pub const KEY_CREATE_LINK = 0x0020;
3796/// Required to create a subkey of a registry key.
3797pub const KEY_CREATE_SUB_KEY = 0x0004;
3798/// Required to enumerate the subkeys of a registry key.
3799pub const KEY_ENUMERATE_SUB_KEYS = 0x0008;
3800/// Equivalent to KEY_READ.
3801pub const KEY_EXECUTE = 0x20019;
3802/// Required to request change notifications for a registry key or for subkeys of a registry key.
3803pub const KEY_NOTIFY = 0x0010;
3804/// Required to query the values of a registry key.
3805pub const KEY_QUERY_VALUE = 0x0001;
3806/// Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values.
3807pub const KEY_READ = 0x20019;
3808/// Required to create, delete, or set a registry value.
3809pub const KEY_SET_VALUE = 0x0002;
3810/// Indicates that an application on 64-bit Windows should operate on the 32-bit registry view.
3811/// This flag is ignored by 32-bit Windows.
3812pub const KEY_WOW64_32KEY = 0x0200;
3813/// Indicates that an application on 64-bit Windows should operate on the 64-bit registry view.
3814/// This flag is ignored by 32-bit Windows.
3815pub const KEY_WOW64_64KEY = 0x0100;
3816/// Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY access rights.
3817pub const KEY_WRITE = 0x20006;
3818
3819/// Open symbolic link.5575/// Open symbolic link.
3820pub const REG_OPTION_OPEN_LINK: DWORD = 0x8;5576pub const REG_OPTION_OPEN_LINK: DWORD = 0x8;
38215577
...@@ -4466,14 +6222,14 @@ pub const EXCEPTION_DISPOSITION = i32;...@@ -4466,14 +6222,14 @@ pub const EXCEPTION_DISPOSITION = i32;
4466pub const EXCEPTION_ROUTINE = *const fn (6222pub const EXCEPTION_ROUTINE = *const fn (
4467 ExceptionRecord: ?*EXCEPTION_RECORD,6223 ExceptionRecord: ?*EXCEPTION_RECORD,
4468 EstablisherFrame: PVOID,6224 EstablisherFrame: PVOID,
4469 ContextRecord: *(Self.CONTEXT),6225 ContextRecord: *CONTEXT,
4470 DispatcherContext: PVOID,6226 DispatcherContext: PVOID,
4471) callconv(.winapi) EXCEPTION_DISPOSITION;6227) callconv(.winapi) EXCEPTION_DISPOSITION;
44726228
4473pub const UNWIND_HISTORY_TABLE_SIZE = 12;6229pub const UNWIND_HISTORY_TABLE_SIZE = 12;
4474pub const UNWIND_HISTORY_TABLE_ENTRY = extern struct {6230pub const UNWIND_HISTORY_TABLE_ENTRY = extern struct {
4475 ImageBase: ULONG64,6231 ImageBase: ULONG64,
4476 FunctionEntry: *Self.RUNTIME_FUNCTION,6232 FunctionEntry: *RUNTIME_FUNCTION,
4477};6233};
44786234
4479pub const UNWIND_HISTORY_TABLE = extern struct {6235pub const UNWIND_HISTORY_TABLE = extern struct {
...@@ -4492,24 +6248,6 @@ pub const UNW_FLAG_EHANDLER = 0x1;...@@ -4492,24 +6248,6 @@ pub const UNW_FLAG_EHANDLER = 0x1;
4492pub const UNW_FLAG_UHANDLER = 0x2;6248pub const UNW_FLAG_UHANDLER = 0x2;
4493pub const UNW_FLAG_CHAININFO = 0x4;6249pub const UNW_FLAG_CHAININFO = 0x4;
44946250
4495pub const OBJECT_ATTRIBUTES = extern struct {
4496 Length: ULONG,
4497 RootDirectory: ?HANDLE,
4498 ObjectName: *UNICODE_STRING,
4499 Attributes: ULONG,
4500 SecurityDescriptor: ?*anyopaque,
4501 SecurityQualityOfService: ?*anyopaque,
4502};
4503
4504pub const OBJ_INHERIT = 0x00000002;
4505pub const OBJ_PERMANENT = 0x00000010;
4506pub const OBJ_EXCLUSIVE = 0x00000020;
4507pub const OBJ_CASE_INSENSITIVE = 0x00000040;
4508pub const OBJ_OPENIF = 0x00000080;
4509pub const OBJ_OPENLINK = 0x00000100;
4510pub const OBJ_KERNEL_HANDLE = 0x00000200;
4511pub const OBJ_VALID_ATTRIBUTES = 0x000003F2;
4512
4513pub const UNICODE_STRING = extern struct {6251pub const UNICODE_STRING = extern struct {
4514 Length: c_ushort,6252 Length: c_ushort,
4515 MaximumLength: c_ushort,6253 MaximumLength: c_ushort,
...@@ -4617,7 +6355,7 @@ pub const PEB = extern struct {...@@ -4617,7 +6355,7 @@ pub const PEB = extern struct {
4617 Ldr: *PEB_LDR_DATA,6355 Ldr: *PEB_LDR_DATA,
4618 ProcessParameters: *RTL_USER_PROCESS_PARAMETERS,6356 ProcessParameters: *RTL_USER_PROCESS_PARAMETERS,
4619 SubSystemData: PVOID,6357 SubSystemData: PVOID,
4620 ProcessHeap: HANDLE,6358 ProcessHeap: ?*HEAP,
46216359
4622 // Versions: 5.1+6360 // Versions: 5.1+
4623 FastPebLock: *RTL_CRITICAL_SECTION,6361 FastPebLock: *RTL_CRITICAL_SECTION,
...@@ -4862,7 +6600,7 @@ pub const FILE_DIRECTORY_INFORMATION = extern struct {...@@ -4862,7 +6600,7 @@ pub const FILE_DIRECTORY_INFORMATION = extern struct {
4862 ChangeTime: LARGE_INTEGER,6600 ChangeTime: LARGE_INTEGER,
4863 EndOfFile: LARGE_INTEGER,6601 EndOfFile: LARGE_INTEGER,
4864 AllocationSize: LARGE_INTEGER,6602 AllocationSize: LARGE_INTEGER,
4865 FileAttributes: ULONG,6603 FileAttributes: FILE.ATTRIBUTE,
4866 FileNameLength: ULONG,6604 FileNameLength: ULONG,
4867 FileName: [1]WCHAR,6605 FileName: [1]WCHAR,
4868};6606};
...@@ -4876,7 +6614,7 @@ pub const FILE_BOTH_DIR_INFORMATION = extern struct {...@@ -4876,7 +6614,7 @@ pub const FILE_BOTH_DIR_INFORMATION = extern struct {
4876 ChangeTime: LARGE_INTEGER,6614 ChangeTime: LARGE_INTEGER,
4877 EndOfFile: LARGE_INTEGER,6615 EndOfFile: LARGE_INTEGER,
4878 AllocationSize: LARGE_INTEGER,6616 AllocationSize: LARGE_INTEGER,
4879 FileAttributes: ULONG,6617 FileAttributes: FILE.ATTRIBUTE,
4880 FileNameLength: ULONG,6618 FileNameLength: ULONG,
4881 EaSize: ULONG,6619 EaSize: ULONG,
4882 ShortNameLength: CHAR,6620 ShortNameLength: CHAR,
...@@ -4905,7 +6643,7 @@ pub fn FileInformationIterator(comptime FileInformationType: type) type {...@@ -4905,7 +6643,7 @@ pub fn FileInformationIterator(comptime FileInformationType: type) type {
4905 };6643 };
4906}6644}
49076645
4908pub const IO_APC_ROUTINE = *const fn (PVOID, *IO_STATUS_BLOCK, ULONG) callconv(.winapi) void;6646pub const IO_APC_ROUTINE = fn (?*anyopaque, *IO_STATUS_BLOCK, ULONG) callconv(.winapi) void;
49096647
4910pub const CURDIR = extern struct {6648pub const CURDIR = extern struct {
4911 DosPath: UNICODE_STRING,6649 DosPath: UNICODE_STRING,
...@@ -4974,7 +6712,7 @@ pub const GetProcessMemoryInfoError = error{...@@ -4974,7 +6712,7 @@ pub const GetProcessMemoryInfoError = error{
49746712
4975pub fn GetProcessMemoryInfo(hProcess: HANDLE) GetProcessMemoryInfoError!VM_COUNTERS {6713pub fn GetProcessMemoryInfo(hProcess: HANDLE) GetProcessMemoryInfoError!VM_COUNTERS {
4976 var vmc: VM_COUNTERS = undefined;6714 var vmc: VM_COUNTERS = undefined;
4977 const rc = ntdll.NtQueryInformationProcess(hProcess, .ProcessVmCounters, &vmc, @sizeOf(VM_COUNTERS), null);6715 const rc = ntdll.NtQueryInformationProcess(hProcess, .VmCounters, &vmc, @sizeOf(VM_COUNTERS), null);
4978 switch (rc) {6716 switch (rc) {
4979 .SUCCESS => return vmc,6717 .SUCCESS => return vmc,
4980 .ACCESS_DENIED => return error.AccessDenied,6718 .ACCESS_DENIED => return error.AccessDenied,
...@@ -5029,7 +6767,7 @@ pub const OSVERSIONINFOW = extern struct {...@@ -5029,7 +6767,7 @@ pub const OSVERSIONINFOW = extern struct {
5029pub const RTL_OSVERSIONINFOW = OSVERSIONINFOW;6767pub const RTL_OSVERSIONINFOW = OSVERSIONINFOW;
50306768
5031pub const REPARSE_DATA_BUFFER = extern struct {6769pub const REPARSE_DATA_BUFFER = extern struct {
5032 ReparseTag: ULONG,6770 ReparseTag: IO_REPARSE_TAG,
5033 ReparseDataLength: USHORT,6771 ReparseDataLength: USHORT,
5034 Reserved: USHORT,6772 Reserved: USHORT,
5035 DataBuffer: [1]UCHAR,6773 DataBuffer: [1]UCHAR,
...@@ -5049,18 +6787,11 @@ pub const MOUNT_POINT_REPARSE_BUFFER = extern struct {...@@ -5049,18 +6787,11 @@ pub const MOUNT_POINT_REPARSE_BUFFER = extern struct {
5049 PrintNameLength: USHORT,6787 PrintNameLength: USHORT,
5050 PathBuffer: [1]WCHAR,6788 PathBuffer: [1]WCHAR,
5051};6789};
5052pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: ULONG = 16 * 1024;
5053pub const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;
5054pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
5055pub const IO_REPARSE_TAG_SYMLINK: ULONG = 0xa000000c;
5056pub const IO_REPARSE_TAG_MOUNT_POINT: ULONG = 0xa0000003;
5057pub const SYMLINK_FLAG_RELATIVE: ULONG = 0x1;6790pub const SYMLINK_FLAG_RELATIVE: ULONG = 0x1;
50586791
5059pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;6792pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;
5060pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2;6793pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2;
50616794
5062pub const MOUNTMGRCONTROLTYPE = 0x0000006D;
5063
5064pub const MOUNTMGR_MOUNT_POINT = extern struct {6795pub const MOUNTMGR_MOUNT_POINT = extern struct {
5065 SymbolicLinkNameOffset: ULONG,6796 SymbolicLinkNameOffset: ULONG,
5066 SymbolicLinkNameLength: USHORT,6797 SymbolicLinkNameLength: USHORT,
...@@ -5077,7 +6808,6 @@ pub const MOUNTMGR_MOUNT_POINTS = extern struct {...@@ -5077,7 +6808,6 @@ pub const MOUNTMGR_MOUNT_POINTS = extern struct {
5077 NumberOfMountPoints: ULONG,6808 NumberOfMountPoints: ULONG,
5078 MountPoints: [1]MOUNTMGR_MOUNT_POINT,6809 MountPoints: [1]MOUNTMGR_MOUNT_POINT,
5079};6810};
5080pub const IOCTL_MOUNTMGR_QUERY_POINTS = CTL_CODE(MOUNTMGRCONTROLTYPE, 2, .METHOD_BUFFERED, FILE_ANY_ACCESS);
50816811
5082pub const MOUNTMGR_TARGET_NAME = extern struct {6812pub const MOUNTMGR_TARGET_NAME = extern struct {
5083 DeviceNameLength: USHORT,6813 DeviceNameLength: USHORT,
...@@ -5087,7 +6817,6 @@ pub const MOUNTMGR_VOLUME_PATHS = extern struct {...@@ -5087,7 +6817,6 @@ pub const MOUNTMGR_VOLUME_PATHS = extern struct {
5087 MultiSzLength: ULONG,6817 MultiSzLength: ULONG,
5088 MultiSz: [1]WCHAR,6818 MultiSz: [1]WCHAR,
5089};6819};
5090pub const IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH = CTL_CODE(MOUNTMGRCONTROLTYPE, 12, .METHOD_BUFFERED, FILE_ANY_ACCESS);
50916820
5092pub const OBJECT_INFORMATION_CLASS = enum(c_int) {6821pub const OBJECT_INFORMATION_CLASS = enum(c_int) {
5093 ObjectBasicInformation = 0,6822 ObjectBasicInformation = 0,
...@@ -5479,113 +7208,6 @@ pub const SYSTEM_BASIC_INFORMATION = extern struct {...@@ -5479,113 +7208,6 @@ pub const SYSTEM_BASIC_INFORMATION = extern struct {
5479 NumberOfProcessors: UCHAR,7208 NumberOfProcessors: UCHAR,
5480};7209};
54817210
5482pub const THREADINFOCLASS = enum(c_int) {
5483 ThreadBasicInformation,
5484 ThreadTimes,
5485 ThreadPriority,
5486 ThreadBasePriority,
5487 ThreadAffinityMask,
5488 ThreadImpersonationToken,
5489 ThreadDescriptorTableEntry,
5490 ThreadEnableAlignmentFaultFixup,
5491 ThreadEventPair_Reusable,
5492 ThreadQuerySetWin32StartAddress,
5493 ThreadZeroTlsCell,
5494 ThreadPerformanceCount,
5495 ThreadAmILastThread,
5496 ThreadIdealProcessor,
5497 ThreadPriorityBoost,
5498 ThreadSetTlsArrayAddress,
5499 ThreadIsIoPending,
5500 // Windows 2000+ from here
5501 ThreadHideFromDebugger,
5502 // Windows XP+ from here
5503 ThreadBreakOnTermination,
5504 ThreadSwitchLegacyState,
5505 ThreadIsTerminated,
5506 // Windows Vista+ from here
5507 ThreadLastSystemCall,
5508 ThreadIoPriority,
5509 ThreadCycleTime,
5510 ThreadPagePriority,
5511 ThreadActualBasePriority,
5512 ThreadTebInformation,
5513 ThreadCSwitchMon,
5514 // Windows 7+ from here
5515 ThreadCSwitchPmu,
5516 ThreadWow64Context,
5517 ThreadGroupInformation,
5518 ThreadUmsInformation,
5519 ThreadCounterProfiling,
5520 ThreadIdealProcessorEx,
5521 // Windows 8+ from here
5522 ThreadCpuAccountingInformation,
5523 // Windows 8.1+ from here
5524 ThreadSuspendCount,
5525 // Windows 10+ from here
5526 ThreadHeterogeneousCpuPolicy,
5527 ThreadContainerId,
5528 ThreadNameInformation,
5529 ThreadSelectedCpuSets,
5530 ThreadSystemThreadInformation,
5531 ThreadActualGroupAffinity,
5532};
5533
5534pub const PROCESSINFOCLASS = enum(c_int) {
5535 ProcessBasicInformation,
5536 ProcessQuotaLimits,
5537 ProcessIoCounters,
5538 ProcessVmCounters,
5539 ProcessTimes,
5540 ProcessBasePriority,
5541 ProcessRaisePriority,
5542 ProcessDebugPort,
5543 ProcessExceptionPort,
5544 ProcessAccessToken,
5545 ProcessLdtInformation,
5546 ProcessLdtSize,
5547 ProcessDefaultHardErrorMode,
5548 ProcessIoPortHandlers,
5549 ProcessPooledUsageAndLimits,
5550 ProcessWorkingSetWatch,
5551 ProcessUserModeIOPL,
5552 ProcessEnableAlignmentFaultFixup,
5553 ProcessPriorityClass,
5554 ProcessWx86Information,
5555 ProcessHandleCount,
5556 ProcessAffinityMask,
5557 ProcessPriorityBoost,
5558 ProcessDeviceMap,
5559 ProcessSessionInformation,
5560 ProcessForegroundInformation,
5561 ProcessWow64Information,
5562 ProcessImageFileName,
5563 ProcessLUIDDeviceMapsEnabled,
5564 ProcessBreakOnTermination,
5565 ProcessDebugObjectHandle,
5566 ProcessDebugFlags,
5567 ProcessHandleTracing,
5568 ProcessIoPriority,
5569 ProcessExecuteFlags,
5570 ProcessTlsInformation,
5571 ProcessCookie,
5572 ProcessImageInformation,
5573 ProcessCycleTime,
5574 ProcessPagePriority,
5575 ProcessInstrumentationCallback,
5576 ProcessThreadStackAllocation,
5577 ProcessWorkingSetWatchEx,
5578 ProcessImageFileNameWin32,
5579 ProcessImageFileMapping,
5580 ProcessAffinityUpdateMode,
5581 ProcessMemoryAllocationMode,
5582 ProcessGroupInformation,
5583 ProcessTokenVirtualizationEnabled,
5584 ProcessConsoleHostProcess,
5585 ProcessWindowInformation,
5586 MaxProcessInfoClass,
5587};
5588
5589pub const PROCESS_BASIC_INFORMATION = extern struct {7211pub const PROCESS_BASIC_INFORMATION = extern struct {
5590 ExitStatus: NTSTATUS,7212 ExitStatus: NTSTATUS,
5591 PebBaseAddress: *PEB,7213 PebBaseAddress: *PEB,
...@@ -5641,7 +7263,7 @@ pub fn ProcessBaseAddress(handle: HANDLE) ProcessBaseAddressError!HMODULE {...@@ -5641,7 +7263,7 @@ pub fn ProcessBaseAddress(handle: HANDLE) ProcessBaseAddressError!HMODULE {
5641 var nread: DWORD = 0;7263 var nread: DWORD = 0;
5642 const rc = ntdll.NtQueryInformationProcess(7264 const rc = ntdll.NtQueryInformationProcess(
5643 handle,7265 handle,
5644 .ProcessBasicInformation,7266 .BasicInformation,
5645 &info,7267 &info,
5646 @sizeOf(PROCESS_BASIC_INFORMATION),7268 @sizeOf(PROCESS_BASIC_INFORMATION),
5647 &nread,7269 &nread,
lib/std/os/windows/kernel32.zig+3-33
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const std = @import("../../std.zig");1const std = @import("../../std.zig");
2const windows = std.os.windows;2const windows = std.os.windows;
33
4const ACCESS_MASK = windows.ACCESS_MASK;
4const BOOL = windows.BOOL;5const BOOL = windows.BOOL;
5const CONDITION_VARIABLE = windows.CONDITION_VARIABLE;6const CONDITION_VARIABLE = windows.CONDITION_VARIABLE;
6const CONSOLE_SCREEN_BUFFER_INFO = windows.CONSOLE_SCREEN_BUFFER_INFO;7const CONSOLE_SCREEN_BUFFER_INFO = windows.CONSOLE_SCREEN_BUFFER_INFO;
...@@ -66,7 +67,7 @@ pub extern "kernel32" fn CancelIoEx(...@@ -66,7 +67,7 @@ pub extern "kernel32" fn CancelIoEx(
6667
67pub extern "kernel32" fn CreateFileW(68pub extern "kernel32" fn CreateFileW(
68 lpFileName: LPCWSTR,69 lpFileName: LPCWSTR,
69 dwDesiredAccess: DWORD,70 dwDesiredAccess: ACCESS_MASK,
70 dwShareMode: DWORD,71 dwShareMode: DWORD,
71 lpSecurityAttributes: ?*SECURITY_ATTRIBUTES,72 lpSecurityAttributes: ?*SECURITY_ATTRIBUTES,
72 dwCreationDisposition: DWORD,73 dwCreationDisposition: DWORD,
...@@ -160,7 +161,7 @@ pub extern "kernel32" fn DuplicateHandle(...@@ -160,7 +161,7 @@ pub extern "kernel32" fn DuplicateHandle(
160 hSourceHandle: HANDLE,161 hSourceHandle: HANDLE,
161 hTargetProcessHandle: HANDLE,162 hTargetProcessHandle: HANDLE,
162 lpTargetHandle: *HANDLE,163 lpTargetHandle: *HANDLE,
163 dwDesiredAccess: DWORD,164 dwDesiredAccess: ACCESS_MASK,
164 bInheritHandle: BOOL,165 bInheritHandle: BOOL,
165 dwOptions: DWORD,166 dwOptions: DWORD,
166) callconv(.winapi) BOOL;167) callconv(.winapi) BOOL;
...@@ -308,9 +309,6 @@ pub extern "kernel32" fn CreateThread(...@@ -308,9 +309,6 @@ pub extern "kernel32" fn CreateThread(
308 lpThreadId: ?*DWORD,309 lpThreadId: ?*DWORD,
309) callconv(.winapi) ?HANDLE;310) callconv(.winapi) ?HANDLE;
310311
311// TODO: Wrapper around RtlDelayExecution.
312pub extern "kernel32" fn SwitchToThread() callconv(.winapi) BOOL;
313
314// Locks, critical sections, initializers312// Locks, critical sections, initializers
315313
316pub extern "kernel32" fn InitOnceExecuteOnce(314pub extern "kernel32" fn InitOnceExecuteOnce(
...@@ -401,34 +399,6 @@ pub extern "kernel32" fn ReadConsoleOutputCharacterW(...@@ -401,34 +399,6 @@ pub extern "kernel32" fn ReadConsoleOutputCharacterW(
401 lpNumberOfCharsRead: *DWORD,399 lpNumberOfCharsRead: *DWORD,
402) callconv(.winapi) BOOL;400) callconv(.winapi) BOOL;
403401
404// Memory Mapping/Allocation
405
406// TODO: Wrapper around RtlCreateHeap.
407pub extern "kernel32" fn HeapCreate(
408 flOptions: DWORD,
409 dwInitialSize: SIZE_T,
410 dwMaximumSize: SIZE_T,
411) callconv(.winapi) ?HANDLE;
412
413// TODO: Fowrarder to RtlFreeHeap before win11_zn.
414// Since win11_zn this function points to unexported symbol RtlFreeHeapFast.
415// See https://github.com/ziglang/zig/pull/25766#discussion_r2479727640
416pub extern "kernel32" fn HeapFree(
417 hHeap: HANDLE,
418 dwFlags: DWORD,
419 lpMem: LPVOID,
420) callconv(.winapi) BOOL;
421
422// TODO: Wrapper around RtlValidateHeap (BOOLEAN -> BOOL)
423pub extern "kernel32" fn HeapValidate(
424 hHeap: HANDLE,
425 dwFlags: DWORD,
426 lpMem: ?*const anyopaque,
427) callconv(.winapi) BOOL;
428
429// TODO: Getter for peb.ProcessHeap
430pub extern "kernel32" fn GetProcessHeap() callconv(.winapi) ?HANDLE;
431
432// Code Libraries/Modules402// Code Libraries/Modules
433403
434// TODO: Wrapper around LdrGetDllFullName.404// TODO: Wrapper around LdrGetDllFullName.
lib/std/os/windows/ntdll.zig+388-263
...@@ -1,277 +1,279 @@...@@ -1,277 +1,279 @@
1const std = @import("../../std.zig");1const std = @import("../../std.zig");
2const windows = std.os.windows;2const windows = std.os.windows;
33
4const ACCESS_MASK = windows.ACCESS_MASK;
4const BOOL = windows.BOOL;5const BOOL = windows.BOOL;
6const BOOLEAN = windows.BOOLEAN;
7const CONDITION_VARIABLE = windows.CONDITION_VARIABLE;
8const CONTEXT = windows.CONTEXT;
9const CRITICAL_SECTION = windows.CRITICAL_SECTION;
10const CTL_CODE = windows.CTL_CODE;
11const CURDIR = windows.CURDIR;
5const DWORD = windows.DWORD;12const DWORD = windows.DWORD;
6const DWORD64 = windows.DWORD64;13const DWORD64 = windows.DWORD64;
7const ULONG = windows.ULONG;14const ERESOURCE = windows.ERESOURCE;
8const ULONG_PTR = windows.ULONG_PTR;15const EVENT_TYPE = windows.EVENT_TYPE;
9const NTSTATUS = windows.NTSTATUS;16const EXCEPTION_ROUTINE = windows.EXCEPTION_ROUTINE;
10const WORD = windows.WORD;17const FILE = windows.FILE;
18const FS_INFORMATION_CLASS = windows.FS_INFORMATION_CLASS;
11const HANDLE = windows.HANDLE;19const HANDLE = windows.HANDLE;
12const ACCESS_MASK = windows.ACCESS_MASK;20const HEAP = windows.HEAP;
13const IO_APC_ROUTINE = windows.IO_APC_ROUTINE;21const IO_APC_ROUTINE = windows.IO_APC_ROUTINE;
14const BOOLEAN = windows.BOOLEAN;
15const OBJECT_ATTRIBUTES = windows.OBJECT_ATTRIBUTES;
16const PVOID = windows.PVOID;
17const IO_STATUS_BLOCK = windows.IO_STATUS_BLOCK;22const IO_STATUS_BLOCK = windows.IO_STATUS_BLOCK;
23const KNONVOLATILE_CONTEXT_POINTERS = windows.KNONVOLATILE_CONTEXT_POINTERS;
18const LARGE_INTEGER = windows.LARGE_INTEGER;24const LARGE_INTEGER = windows.LARGE_INTEGER;
25const LOGICAL = windows.LOGICAL;
26const LONG = windows.LONG;
27const LPCVOID = windows.LPCVOID;
28const LPVOID = windows.LPVOID;
29const MEM = windows.MEM;
30const NTSTATUS = windows.NTSTATUS;
31const OBJECT_ATTRIBUTES = windows.OBJECT_ATTRIBUTES;
19const OBJECT_INFORMATION_CLASS = windows.OBJECT_INFORMATION_CLASS;32const OBJECT_INFORMATION_CLASS = windows.OBJECT_INFORMATION_CLASS;
20const FILE_INFORMATION_CLASS = windows.FILE_INFORMATION_CLASS;33const PAGE = windows.PAGE;
21const FS_INFORMATION_CLASS = windows.FS_INFORMATION_CLASS;
22const UNICODE_STRING = windows.UNICODE_STRING;
23const RTL_OSVERSIONINFOW = windows.RTL_OSVERSIONINFOW;
24const FILE_BASIC_INFORMATION = windows.FILE_BASIC_INFORMATION;
25const SIZE_T = windows.SIZE_T;
26const CURDIR = windows.CURDIR;
27const PCWSTR = windows.PCWSTR;34const PCWSTR = windows.PCWSTR;
35const PROCESSINFOCLASS = windows.PROCESSINFOCLASS;
36const PVOID = windows.PVOID;
37const RTL_OSVERSIONINFOW = windows.RTL_OSVERSIONINFOW;
28const RTL_QUERY_REGISTRY_TABLE = windows.RTL_QUERY_REGISTRY_TABLE;38const RTL_QUERY_REGISTRY_TABLE = windows.RTL_QUERY_REGISTRY_TABLE;
29const CONTEXT = windows.CONTEXT;
30const UNWIND_HISTORY_TABLE = windows.UNWIND_HISTORY_TABLE;
31const RUNTIME_FUNCTION = windows.RUNTIME_FUNCTION;39const RUNTIME_FUNCTION = windows.RUNTIME_FUNCTION;
32const KNONVOLATILE_CONTEXT_POINTERS = windows.KNONVOLATILE_CONTEXT_POINTERS;40const SEC = windows.SEC;
33const EXCEPTION_ROUTINE = windows.EXCEPTION_ROUTINE;41const SECTION_INHERIT = windows.SECTION_INHERIT;
42const SIZE_T = windows.SIZE_T;
43const SRWLOCK = windows.SRWLOCK;
34const SYSTEM_INFORMATION_CLASS = windows.SYSTEM_INFORMATION_CLASS;44const SYSTEM_INFORMATION_CLASS = windows.SYSTEM_INFORMATION_CLASS;
35const THREADINFOCLASS = windows.THREADINFOCLASS;45const THREADINFOCLASS = windows.THREADINFOCLASS;
36const PROCESSINFOCLASS = windows.PROCESSINFOCLASS;46const ULONG = windows.ULONG;
37const LPVOID = windows.LPVOID;47const ULONG_PTR = windows.ULONG_PTR;
38const LPCVOID = windows.LPCVOID;48const UNICODE_STRING = windows.UNICODE_STRING;
39const SECTION_INHERIT = windows.SECTION_INHERIT;49const UNWIND_HISTORY_TABLE = windows.UNWIND_HISTORY_TABLE;
50const USHORT = windows.USHORT;
40const VECTORED_EXCEPTION_HANDLER = windows.VECTORED_EXCEPTION_HANDLER;51const VECTORED_EXCEPTION_HANDLER = windows.VECTORED_EXCEPTION_HANDLER;
41const CRITICAL_SECTION = windows.CRITICAL_SECTION;52const WORD = windows.WORD;
42const SRWLOCK = windows.SRWLOCK;
43const CONDITION_VARIABLE = windows.CONDITION_VARIABLE;
4453
45pub extern "ntdll" fn NtQueryInformationProcess(54// ref: km/ntifs.h
46 ProcessHandle: HANDLE,
47 ProcessInformationClass: PROCESSINFOCLASS,
48 ProcessInformation: *anyopaque,
49 ProcessInformationLength: ULONG,
50 ReturnLength: ?*ULONG,
51) callconv(.winapi) NTSTATUS;
5255
53pub extern "ntdll" fn NtQueryInformationThread(56pub extern "ntdll" fn RtlCreateHeap(
54 ThreadHandle: HANDLE,57 Flags: HEAP.FLAGS.CREATE,
55 ThreadInformationClass: THREADINFOCLASS,58 HeapBase: ?PVOID,
56 ThreadInformation: *anyopaque,59 ReserveSize: SIZE_T,
57 ThreadInformationLength: ULONG,60 CommitSize: SIZE_T,
58 ReturnLength: ?*ULONG,61 Lock: ?*ERESOURCE,
59) callconv(.winapi) NTSTATUS;62 Parameters: ?*const HEAP.RTL_PARAMETERS,
63) callconv(.winapi) ?*HEAP;
6064
61pub extern "ntdll" fn NtQuerySystemInformation(65pub extern "ntdll" fn RtlDestroyHeap(
62 SystemInformationClass: SYSTEM_INFORMATION_CLASS,66 HeapHandle: *HEAP,
63 SystemInformation: PVOID,67) callconv(.winapi) ?*HEAP;
64 SystemInformationLength: ULONG,
65 ReturnLength: ?*ULONG,
66) callconv(.winapi) NTSTATUS;
6768
68pub extern "ntdll" fn NtSetInformationThread(69pub extern "ntdll" fn RtlAllocateHeap(
69 ThreadHandle: HANDLE,70 HeapHandle: *HEAP,
70 ThreadInformationClass: THREADINFOCLASS,71 Flags: HEAP.FLAGS.ALLOCATION,
71 ThreadInformation: *const anyopaque,72 Size: SIZE_T,
72 ThreadInformationLength: ULONG,73) callconv(.winapi) ?PVOID;
73) callconv(.winapi) NTSTATUS;74
75pub extern "ntdll" fn RtlFreeHeap(
76 HeapHandle: *HEAP,
77 Flags: HEAP.FLAGS.ALLOCATION,
78 BaseAddress: ?PVOID,
79) callconv(.winapi) LOGICAL;
7480
75pub extern "ntdll" fn RtlGetVersion(
76 lpVersionInformation: *RTL_OSVERSIONINFOW,
77) callconv(.winapi) NTSTATUS;
78pub extern "ntdll" fn RtlCaptureStackBackTrace(81pub extern "ntdll" fn RtlCaptureStackBackTrace(
79 FramesToSkip: DWORD,82 FramesToSkip: ULONG,
80 FramesToCapture: DWORD,83 FramesToCapture: ULONG,
81 BackTrace: **anyopaque,84 BackTrace: **anyopaque,
82 BackTraceHash: ?*DWORD,85 BackTraceHash: ?*ULONG,
83) callconv(.winapi) WORD;86) callconv(.winapi) USHORT;
84pub extern "ntdll" fn RtlCaptureContext(ContextRecord: *CONTEXT) callconv(.winapi) void;
85pub extern "ntdll" fn RtlLookupFunctionEntry(
86 ControlPc: DWORD64,
87 ImageBase: *DWORD64,
88 HistoryTable: *UNWIND_HISTORY_TABLE,
89) callconv(.winapi) ?*RUNTIME_FUNCTION;
90pub extern "ntdll" fn RtlVirtualUnwind(
91 HandlerType: DWORD,
92 ImageBase: DWORD64,
93 ControlPc: DWORD64,
94 FunctionEntry: *RUNTIME_FUNCTION,
95 ContextRecord: *CONTEXT,
96 HandlerData: *?PVOID,
97 EstablisherFrame: *DWORD64,
98 ContextPointers: ?*KNONVOLATILE_CONTEXT_POINTERS,
99) callconv(.winapi) *EXCEPTION_ROUTINE;
100pub extern "ntdll" fn RtlGetSystemTimePrecise() callconv(.winapi) LARGE_INTEGER;
101pub extern "ntdll" fn NtQueryInformationFile(
102 FileHandle: HANDLE,
103 IoStatusBlock: *IO_STATUS_BLOCK,
104 FileInformation: *anyopaque,
105 Length: ULONG,
106 FileInformationClass: FILE_INFORMATION_CLASS,
107) callconv(.winapi) NTSTATUS;
108pub extern "ntdll" fn NtSetInformationFile(
109 FileHandle: HANDLE,
110 IoStatusBlock: *IO_STATUS_BLOCK,
111 FileInformation: PVOID,
112 Length: ULONG,
113 FileInformationClass: FILE_INFORMATION_CLASS,
114) callconv(.winapi) NTSTATUS;
11587
116pub extern "ntdll" fn NtQueryAttributesFile(88pub extern "ntdll" fn RtlCaptureContext(
117 ObjectAttributes: *OBJECT_ATTRIBUTES,89 ContextRecord: *CONTEXT,
118 FileAttributes: *FILE_BASIC_INFORMATION,90) callconv(.winapi) void;
119) callconv(.winapi) NTSTATUS;
12091
121pub extern "ntdll" fn RtlQueryPerformanceCounter(PerformanceCounter: *LARGE_INTEGER) callconv(.winapi) BOOL;92pub extern "ntdll" fn NtSetInformationThread(
122pub extern "ntdll" fn RtlQueryPerformanceFrequency(PerformanceFrequency: *LARGE_INTEGER) callconv(.winapi) BOOL;93 ThreadHandle: HANDLE,
123pub extern "ntdll" fn NtQueryPerformanceCounter(94 ThreadInformationClass: THREADINFOCLASS,
124 PerformanceCounter: *LARGE_INTEGER,95 ThreadInformation: *const anyopaque,
125 PerformanceFrequency: ?*LARGE_INTEGER,96 ThreadInformationLength: ULONG,
126) callconv(.winapi) NTSTATUS;97) callconv(.winapi) NTSTATUS;
12798
128pub extern "ntdll" fn NtCreateFile(99pub extern "ntdll" fn NtCreateFile(
129 FileHandle: *HANDLE,100 FileHandle: *HANDLE,
130 DesiredAccess: ACCESS_MASK,101 DesiredAccess: ACCESS_MASK,
131 ObjectAttributes: *OBJECT_ATTRIBUTES,102 ObjectAttributes: *const OBJECT_ATTRIBUTES,
132 IoStatusBlock: *IO_STATUS_BLOCK,103 IoStatusBlock: *IO_STATUS_BLOCK,
133 AllocationSize: ?*LARGE_INTEGER,104 AllocationSize: ?*const LARGE_INTEGER,
134 FileAttributes: ULONG,105 FileAttributes: FILE.ATTRIBUTE,
135 ShareAccess: ULONG,106 ShareAccess: FILE.SHARE,
136 CreateDisposition: ULONG,107 CreateDisposition: FILE.CREATE_DISPOSITION,
137 CreateOptions: ULONG,108 CreateOptions: FILE.MODE,
138 EaBuffer: ?*anyopaque,109 EaBuffer: ?*anyopaque,
139 EaLength: ULONG,110 EaLength: ULONG,
140) callconv(.winapi) NTSTATUS;111) callconv(.winapi) NTSTATUS;
141pub extern "ntdll" fn NtCreateSection(112
142 SectionHandle: *HANDLE,
143 DesiredAccess: ACCESS_MASK,
144 ObjectAttributes: ?*OBJECT_ATTRIBUTES,
145 MaximumSize: ?*LARGE_INTEGER,
146 SectionPageProtection: ULONG,
147 AllocationAttributes: ULONG,
148 FileHandle: ?HANDLE,
149) callconv(.winapi) NTSTATUS;
150pub extern "ntdll" fn NtMapViewOfSection(
151 SectionHandle: HANDLE,
152 ProcessHandle: HANDLE,
153 BaseAddress: *PVOID,
154 ZeroBits: ?*ULONG,
155 CommitSize: SIZE_T,
156 SectionOffset: ?*LARGE_INTEGER,
157 ViewSize: *SIZE_T,
158 InheritDispostion: SECTION_INHERIT,
159 AllocationType: ULONG,
160 Win32Protect: ULONG,
161) callconv(.winapi) NTSTATUS;
162pub extern "ntdll" fn NtUnmapViewOfSection(
163 ProcessHandle: HANDLE,
164 BaseAddress: PVOID,
165) callconv(.winapi) NTSTATUS;
166pub extern "ntdll" fn NtDeviceIoControlFile(113pub extern "ntdll" fn NtDeviceIoControlFile(
167 FileHandle: HANDLE,114 FileHandle: HANDLE,
168 Event: ?HANDLE,115 Event: ?HANDLE,
169 ApcRoutine: ?IO_APC_ROUTINE,116 ApcRoutine: ?*const IO_APC_ROUTINE,
170 ApcContext: ?*anyopaque,117 ApcContext: ?*anyopaque,
171 IoStatusBlock: *IO_STATUS_BLOCK,118 IoStatusBlock: *IO_STATUS_BLOCK,
172 IoControlCode: ULONG,119 IoControlCode: CTL_CODE,
173 InputBuffer: ?*const anyopaque,120 InputBuffer: ?*const anyopaque,
174 InputBufferLength: ULONG,121 InputBufferLength: ULONG,
175 OutputBuffer: ?PVOID,122 OutputBuffer: ?PVOID,
176 OutputBufferLength: ULONG,123 OutputBufferLength: ULONG,
177) callconv(.winapi) NTSTATUS;124) callconv(.winapi) NTSTATUS;
125
178pub extern "ntdll" fn NtFsControlFile(126pub extern "ntdll" fn NtFsControlFile(
179 FileHandle: HANDLE,127 FileHandle: HANDLE,
180 Event: ?HANDLE,128 Event: ?HANDLE,
181 ApcRoutine: ?IO_APC_ROUTINE,129 ApcRoutine: ?*const IO_APC_ROUTINE,
182 ApcContext: ?*anyopaque,130 ApcContext: ?*anyopaque,
183 IoStatusBlock: *IO_STATUS_BLOCK,131 IoStatusBlock: *IO_STATUS_BLOCK,
184 FsControlCode: ULONG,132 FsControlCode: CTL_CODE,
185 InputBuffer: ?*const anyopaque,133 InputBuffer: ?*const anyopaque,
186 InputBufferLength: ULONG,134 InputBufferLength: ULONG,
187 OutputBuffer: ?PVOID,135 OutputBuffer: ?PVOID,
188 OutputBufferLength: ULONG,136 OutputBufferLength: ULONG,
189) callconv(.winapi) NTSTATUS;137) callconv(.winapi) NTSTATUS;
190pub extern "ntdll" fn NtClose(Handle: HANDLE) callconv(.winapi) NTSTATUS;
191pub extern "ntdll" fn RtlDosPathNameToNtPathName_U(
192 DosPathName: [*:0]const u16,
193 NtPathName: *UNICODE_STRING,
194 NtFileNamePart: ?*?[*:0]const u16,
195 DirectoryInfo: ?*CURDIR,
196) callconv(.winapi) BOOL;
197pub extern "ntdll" fn RtlFreeUnicodeString(UnicodeString: *UNICODE_STRING) callconv(.winapi) void;
198138
199/// Returns the number of bytes written to `Buffer`.139pub extern "ntdll" fn NtLockFile(
200/// If the returned count is larger than `BufferByteLength`, the buffer was too small.140 FileHandle: HANDLE,
201/// If the returned count is zero, an error occurred.141 Event: ?HANDLE,
202pub extern "ntdll" fn RtlGetFullPathName_U(142 ApcRoutine: ?*const IO_APC_ROUTINE,
203 FileName: [*:0]const u16,143 ApcContext: ?*anyopaque,
204 BufferByteLength: ULONG,144 IoStatusBlock: *IO_STATUS_BLOCK,
205 Buffer: [*]u16,145 ByteOffset: *const LARGE_INTEGER,
206 ShortName: ?*[*:0]const u16,146 Length: *const LARGE_INTEGER,
207) callconv(.winapi) windows.ULONG;147 Key: ?*const ULONG,
148 FailImmediately: BOOLEAN,
149 ExclusiveLock: BOOLEAN,
150) callconv(.winapi) NTSTATUS;
151
152pub extern "ntdll" fn NtOpenFile(
153 FileHandle: *HANDLE,
154 DesiredAccess: ACCESS_MASK,
155 ObjectAttributes: *const OBJECT_ATTRIBUTES,
156 IoStatusBlock: *IO_STATUS_BLOCK,
157 ShareAccess: FILE.SHARE,
158 OpenOptions: FILE.MODE,
159) callconv(.winapi) NTSTATUS;
208160
209pub extern "ntdll" fn NtQueryDirectoryFile(161pub extern "ntdll" fn NtQueryDirectoryFile(
210 FileHandle: HANDLE,162 FileHandle: HANDLE,
211 Event: ?HANDLE,163 Event: ?HANDLE,
212 ApcRoutine: ?IO_APC_ROUTINE,164 ApcRoutine: ?*const IO_APC_ROUTINE,
213 ApcContext: ?*anyopaque,165 ApcContext: ?*anyopaque,
214 IoStatusBlock: *IO_STATUS_BLOCK,166 IoStatusBlock: *IO_STATUS_BLOCK,
215 FileInformation: *anyopaque,167 FileInformation: *anyopaque,
216 Length: ULONG,168 Length: ULONG,
217 FileInformationClass: FILE_INFORMATION_CLASS,169 FileInformationClass: FILE.INFORMATION_CLASS,
218 ReturnSingleEntry: BOOLEAN,170 ReturnSingleEntry: BOOLEAN,
219 FileName: ?*UNICODE_STRING,171 FileName: ?*const UNICODE_STRING,
220 RestartScan: BOOLEAN,172 RestartScan: BOOLEAN,
221) callconv(.winapi) NTSTATUS;173) callconv(.winapi) NTSTATUS;
222174
223pub extern "ntdll" fn NtCreateKeyedEvent(175pub extern "ntdll" fn NtQueryInformationFile(
224 KeyedEventHandle: *HANDLE,176 FileHandle: HANDLE,
225 DesiredAccess: ACCESS_MASK,177 IoStatusBlock: *IO_STATUS_BLOCK,
226 ObjectAttributes: ?PVOID,178 FileInformation: *anyopaque,
227 Flags: ULONG,179 Length: ULONG,
180 FileInformationClass: FILE.INFORMATION_CLASS,
228) callconv(.winapi) NTSTATUS;181) callconv(.winapi) NTSTATUS;
229182
230pub extern "ntdll" fn NtReleaseKeyedEvent(183pub extern "ntdll" fn NtQueryVolumeInformationFile(
231 EventHandle: ?HANDLE,184 FileHandle: HANDLE,
232 Key: ?*const anyopaque,185 IoStatusBlock: *IO_STATUS_BLOCK,
233 Alertable: BOOLEAN,186 FsInformation: *anyopaque,
234 Timeout: ?*const LARGE_INTEGER,187 Length: ULONG,
188 FsInformationClass: FS_INFORMATION_CLASS,
235) callconv(.winapi) NTSTATUS;189) callconv(.winapi) NTSTATUS;
236190
237pub extern "ntdll" fn NtWaitForKeyedEvent(191pub extern "ntdll" fn NtReadFile(
238 EventHandle: ?HANDLE,192 FileHandle: HANDLE,
239 Key: ?*const anyopaque,193 Event: ?HANDLE,
240 Alertable: BOOLEAN,194 ApcRoutine: ?*const IO_APC_ROUTINE,
241 Timeout: ?*const LARGE_INTEGER,195 ApcContext: ?*anyopaque,
196 IoStatusBlock: *IO_STATUS_BLOCK,
197 Buffer: *anyopaque,
198 Length: ULONG,
199 ByteOffset: ?*const LARGE_INTEGER,
200 Key: ?*const ULONG,
201) callconv(.winapi) NTSTATUS;
202
203pub extern "ntdll" fn NtSetInformationFile(
204 FileHandle: HANDLE,
205 IoStatusBlock: *IO_STATUS_BLOCK,
206 FileInformation: *const anyopaque,
207 Length: ULONG,
208 FileInformationClass: FILE.INFORMATION_CLASS,
209) callconv(.winapi) NTSTATUS;
210
211pub extern "ntdll" fn NtWriteFile(
212 FileHandle: HANDLE,
213 Event: ?HANDLE,
214 ApcRoutine: ?*const IO_APC_ROUTINE,
215 ApcContext: ?*anyopaque,
216 IoStatusBlock: *IO_STATUS_BLOCK,
217 Buffer: *const anyopaque,
218 Length: ULONG,
219 ByteOffset: ?*const LARGE_INTEGER,
220 Key: ?*const ULONG,
242) callconv(.winapi) NTSTATUS;221) callconv(.winapi) NTSTATUS;
243222
244pub extern "ntdll" fn RtlSetCurrentDirectory_U(PathName: *UNICODE_STRING) callconv(.winapi) NTSTATUS;223pub extern "ntdll" fn NtUnlockFile(
224 FileHandle: HANDLE,
225 IoStatusBlock: *IO_STATUS_BLOCK,
226 ByteOffset: *const LARGE_INTEGER,
227 Length: *const LARGE_INTEGER,
228 Key: ULONG,
229) callconv(.winapi) NTSTATUS;
245230
246pub extern "ntdll" fn NtQueryObject(231pub extern "ntdll" fn NtQueryObject(
247 Handle: HANDLE,232 Handle: HANDLE,
248 ObjectInformationClass: OBJECT_INFORMATION_CLASS,233 ObjectInformationClass: OBJECT_INFORMATION_CLASS,
249 ObjectInformation: PVOID,234 ObjectInformation: ?PVOID,
250 ObjectInformationLength: ULONG,235 ObjectInformationLength: ULONG,
251 ReturnLength: ?*ULONG,236 ReturnLength: ?*ULONG,
252) callconv(.winapi) NTSTATUS;237) callconv(.winapi) NTSTATUS;
253238
254pub extern "ntdll" fn NtQueryVolumeInformationFile(239pub extern "ntdll" fn NtClose(
255 FileHandle: HANDLE,240 Handle: HANDLE,
256 IoStatusBlock: *IO_STATUS_BLOCK,
257 FsInformation: *anyopaque,
258 Length: ULONG,
259 FsInformationClass: FS_INFORMATION_CLASS,
260) callconv(.winapi) NTSTATUS;241) callconv(.winapi) NTSTATUS;
261242
262pub extern "ntdll" fn RtlWakeAddressAll(243pub extern "ntdll" fn NtCreateSection(
263 Address: ?*const anyopaque,244 SectionHandle: *HANDLE,
264) callconv(.winapi) void;245 DesiredAccess: ACCESS_MASK,
246 ObjectAttributes: ?*const OBJECT_ATTRIBUTES,
247 MaximumSize: ?*const LARGE_INTEGER,
248 SectionPageProtection: PAGE,
249 AllocationAttributes: SEC,
250 FileHandle: ?HANDLE,
251) callconv(.winapi) NTSTATUS;
265252
266pub extern "ntdll" fn RtlWakeAddressSingle(253pub extern "ntdll" fn NtAllocateVirtualMemory(
267 Address: ?*const anyopaque,254 ProcessHandle: HANDLE,
268) callconv(.winapi) void;255 BaseAddress: *PVOID,
256 ZeroBits: ULONG_PTR,
257 RegionSize: *SIZE_T,
258 AllocationType: MEM.ALLOCATE,
259 Protect: PAGE,
260) callconv(.winapi) NTSTATUS;
269261
270pub extern "ntdll" fn RtlWaitOnAddress(262pub extern "ntdll" fn NtFreeVirtualMemory(
271 Address: ?*const anyopaque,263 ProcessHandle: HANDLE,
272 CompareAddress: ?*const anyopaque,264 BaseAddress: *PVOID,
273 AddressSize: SIZE_T,265 RegionSize: *SIZE_T,
274 Timeout: ?*const LARGE_INTEGER,266 FreeType: MEM.FREE,
267) callconv(.winapi) NTSTATUS;
268
269// ref: km/wdm.h
270
271pub extern "ntdll" fn RtlQueryRegistryValues(
272 RelativeTo: ULONG,
273 Path: PCWSTR,
274 QueryTable: [*]RTL_QUERY_REGISTRY_TABLE,
275 Context: ?*const anyopaque,
276 Environment: ?*const anyopaque,
275) callconv(.winapi) NTSTATUS;277) callconv(.winapi) NTSTATUS;
276278
277pub extern "ntdll" fn RtlEqualUnicodeString(279pub extern "ntdll" fn RtlEqualUnicodeString(
...@@ -284,39 +286,153 @@ pub extern "ntdll" fn RtlUpcaseUnicodeChar(...@@ -284,39 +286,153 @@ pub extern "ntdll" fn RtlUpcaseUnicodeChar(
284 SourceCharacter: u16,286 SourceCharacter: u16,
285) callconv(.winapi) u16;287) callconv(.winapi) u16;
286288
287pub extern "ntdll" fn NtLockFile(289pub extern "ntdll" fn RtlFreeUnicodeString(
288 FileHandle: HANDLE,290 UnicodeString: *UNICODE_STRING,
289 Event: ?HANDLE,291) callconv(.winapi) void;
290 ApcRoutine: ?*IO_APC_ROUTINE,292
291 ApcContext: ?*anyopaque,293pub extern "ntdll" fn RtlGetVersion(
292 IoStatusBlock: *IO_STATUS_BLOCK,294 lpVersionInformation: *RTL_OSVERSIONINFOW,
293 ByteOffset: *const LARGE_INTEGER,
294 Length: *const LARGE_INTEGER,
295 Key: ?*ULONG,
296 FailImmediately: BOOLEAN,
297 ExclusiveLock: BOOLEAN,
298) callconv(.winapi) NTSTATUS;295) callconv(.winapi) NTSTATUS;
299296
300pub extern "ntdll" fn NtUnlockFile(297// ref: um/winnt.h
301 FileHandle: HANDLE,298
299pub extern "ntdll" fn RtlLookupFunctionEntry(
300 ControlPc: usize,
301 ImageBase: *usize,
302 HistoryTable: *UNWIND_HISTORY_TABLE,
303) callconv(.winapi) ?*RUNTIME_FUNCTION;
304
305pub extern "ntdll" fn RtlVirtualUnwind(
306 HandlerType: DWORD,
307 ImageBase: usize,
308 ControlPc: usize,
309 FunctionEntry: *RUNTIME_FUNCTION,
310 ContextRecord: *CONTEXT,
311 HandlerData: *?PVOID,
312 EstablisherFrame: *usize,
313 ContextPointers: ?*KNONVOLATILE_CONTEXT_POINTERS,
314) callconv(.winapi) *EXCEPTION_ROUTINE;
315
316// ref: um/winternl.h
317
318pub extern "ntdll" fn NtWaitForSingleObject(
319 Handle: HANDLE,
320 Alertable: BOOLEAN,
321 Timeout: ?*const LARGE_INTEGER,
322) callconv(.winapi) NTSTATUS;
323
324pub extern "ntdll" fn NtQueryInformationProcess(
325 ProcessHandle: HANDLE,
326 ProcessInformationClass: PROCESSINFOCLASS,
327 ProcessInformation: *anyopaque,
328 ProcessInformationLength: ULONG,
329 ReturnLength: ?*ULONG,
330) callconv(.winapi) NTSTATUS;
331
332pub extern "ntdll" fn NtQueryInformationThread(
333 ThreadHandle: HANDLE,
334 ThreadInformationClass: THREADINFOCLASS,
335 ThreadInformation: *anyopaque,
336 ThreadInformationLength: ULONG,
337 ReturnLength: ?*ULONG,
338) callconv(.winapi) NTSTATUS;
339
340pub extern "ntdll" fn NtQuerySystemInformation(
341 SystemInformationClass: SYSTEM_INFORMATION_CLASS,
342 SystemInformation: PVOID,
343 SystemInformationLength: ULONG,
344 ReturnLength: ?*ULONG,
345) callconv(.winapi) NTSTATUS;
346
347// ref none
348
349pub extern "ntdll" fn NtQueryAttributesFile(
350 ObjectAttributes: *const OBJECT_ATTRIBUTES,
351 FileAttributes: *FILE.BASIC_INFORMATION,
352) callconv(.winapi) NTSTATUS;
353
354pub extern "ntdll" fn NtCreateEvent(
355 EventHandle: *HANDLE,
356 DesiredAccess: ACCESS_MASK,
357 ObjectAttributes: ?*const OBJECT_ATTRIBUTES,
358 EventType: EVENT_TYPE,
359 InitialState: BOOLEAN,
360) callconv(.winapi) NTSTATUS;
361pub extern "ntdll" fn NtSetEvent(
362 EventHandle: HANDLE,
363 PreviousState: ?*LONG,
364) callconv(.winapi) NTSTATUS;
365
366pub extern "ntdll" fn NtCreateKeyedEvent(
367 KeyedEventHandle: *HANDLE,
368 DesiredAccess: ACCESS_MASK,
369 ObjectAttributes: ?*const OBJECT_ATTRIBUTES,
370 Flags: ULONG,
371) callconv(.winapi) NTSTATUS;
372pub extern "ntdll" fn NtReleaseKeyedEvent(
373 EventHandle: ?HANDLE,
374 Key: ?*const anyopaque,
375 Alertable: BOOLEAN,
376 Timeout: ?*const LARGE_INTEGER,
377) callconv(.winapi) NTSTATUS;
378pub extern "ntdll" fn NtWaitForKeyedEvent(
379 EventHandle: ?HANDLE,
380 Key: ?*const anyopaque,
381 Alertable: BOOLEAN,
382 Timeout: ?*const LARGE_INTEGER,
383) callconv(.winapi) NTSTATUS;
384
385pub extern "ntdll" fn NtCreateNamedPipeFile(
386 FileHandle: *HANDLE,
387 DesiredAccess: ACCESS_MASK,
388 ObjectAttributes: *const OBJECT_ATTRIBUTES,
302 IoStatusBlock: *IO_STATUS_BLOCK,389 IoStatusBlock: *IO_STATUS_BLOCK,
303 ByteOffset: *const LARGE_INTEGER,390 ShareAccess: FILE.SHARE,
304 Length: *const LARGE_INTEGER,391 CreateDisposition: FILE.CREATE_DISPOSITION,
305 Key: ?*ULONG,392 CreateOptions: FILE.MODE,
393 NamedPipeType: FILE.PIPE.TYPE,
394 ReadMode: FILE.PIPE.READ_MODE,
395 CompletionMode: FILE.PIPE.COMPLETION_MODE,
396 MaximumInstances: ULONG,
397 InboundQuota: ULONG,
398 OutboundQuota: ULONG,
399 DefaultTimeout: ?*const LARGE_INTEGER,
400) callconv(.winapi) NTSTATUS;
401
402pub extern "ntdll" fn NtMapViewOfSection(
403 SectionHandle: HANDLE,
404 ProcessHandle: HANDLE,
405 BaseAddress: ?*PVOID,
406 ZeroBits: ?*const ULONG,
407 CommitSize: SIZE_T,
408 SectionOffset: ?*LARGE_INTEGER,
409 ViewSize: *SIZE_T,
410 InheritDispostion: SECTION_INHERIT,
411 AllocationType: MEM.MAP,
412 PageProtection: PAGE,
413) callconv(.winapi) NTSTATUS;
414pub extern "ntdll" fn NtUnmapViewOfSection(
415 ProcessHandle: HANDLE,
416 BaseAddress: PVOID,
417) callconv(.winapi) NTSTATUS;
418pub extern "ntdll" fn NtUnmapViewOfSectionEx(
419 ProcessHandle: HANDLE,
420 BaseAddress: PVOID,
421 UnmapFlags: MEM.UNMAP,
306) callconv(.winapi) NTSTATUS;422) callconv(.winapi) NTSTATUS;
307423
308pub extern "ntdll" fn NtOpenKey(424pub extern "ntdll" fn NtOpenKey(
309 KeyHandle: *HANDLE,425 KeyHandle: *HANDLE,
310 DesiredAccess: ACCESS_MASK,426 DesiredAccess: ACCESS_MASK,
311 ObjectAttributes: OBJECT_ATTRIBUTES,427 ObjectAttributes: *const OBJECT_ATTRIBUTES,
312) callconv(.winapi) NTSTATUS;428) callconv(.winapi) NTSTATUS;
313429
314pub extern "ntdll" fn RtlQueryRegistryValues(430pub extern "ntdll" fn NtQueueApcThread(
315 RelativeTo: ULONG,431 ThreadHandle: HANDLE,
316 Path: PCWSTR,432 ApcRoutine: *const IO_APC_ROUTINE,
317 QueryTable: [*]RTL_QUERY_REGISTRY_TABLE,433 ApcArgument1: ?*anyopaque,
318 Context: ?*anyopaque,434 ApcArgument2: ?*anyopaque,
319 Environment: ?*anyopaque,435 ApcArgument3: ?*anyopaque,
320) callconv(.winapi) NTSTATUS;436) callconv(.winapi) NTSTATUS;
321437
322pub extern "ntdll" fn NtReadVirtualMemory(438pub extern "ntdll" fn NtReadVirtualMemory(
...@@ -326,7 +442,6 @@ pub extern "ntdll" fn NtReadVirtualMemory(...@@ -326,7 +442,6 @@ pub extern "ntdll" fn NtReadVirtualMemory(
326 NumberOfBytesToRead: SIZE_T,442 NumberOfBytesToRead: SIZE_T,
327 NumberOfBytesRead: ?*SIZE_T,443 NumberOfBytesRead: ?*SIZE_T,
328) callconv(.winapi) NTSTATUS;444) callconv(.winapi) NTSTATUS;
329
330pub extern "ntdll" fn NtWriteVirtualMemory(445pub extern "ntdll" fn NtWriteVirtualMemory(
331 ProcessHandle: HANDLE,446 ProcessHandle: HANDLE,
332 BaseAddress: ?PVOID,447 BaseAddress: ?PVOID,
...@@ -334,51 +449,15 @@ pub extern "ntdll" fn NtWriteVirtualMemory(...@@ -334,51 +449,15 @@ pub extern "ntdll" fn NtWriteVirtualMemory(
334 NumberOfBytesToWrite: SIZE_T,449 NumberOfBytesToWrite: SIZE_T,
335 NumberOfBytesWritten: ?*SIZE_T,450 NumberOfBytesWritten: ?*SIZE_T,
336) callconv(.winapi) NTSTATUS;451) callconv(.winapi) NTSTATUS;
337
338pub extern "ntdll" fn NtProtectVirtualMemory(452pub extern "ntdll" fn NtProtectVirtualMemory(
339 ProcessHandle: HANDLE,453 ProcessHandle: HANDLE,
340 BaseAddress: *?PVOID,454 BaseAddress: *?PVOID,
341 NumberOfBytesToProtect: *SIZE_T,455 NumberOfBytesToProtect: *SIZE_T,
342 NewAccessProtection: ULONG,456 NewAccessProtection: PAGE,
343 OldAccessProtection: *ULONG,457 OldAccessProtection: *PAGE,
344) callconv(.winapi) NTSTATUS;458) callconv(.winapi) NTSTATUS;
345459
346pub extern "ntdll" fn RtlExitUserProcess(460pub extern "ntdll" fn NtYieldExecution() callconv(.winapi) NTSTATUS;
347 ExitStatus: u32,
348) callconv(.winapi) noreturn;
349
350pub extern "ntdll" fn NtCreateNamedPipeFile(
351 FileHandle: *HANDLE,
352 DesiredAccess: ULONG,
353 ObjectAttributes: *OBJECT_ATTRIBUTES,
354 IoStatusBlock: *IO_STATUS_BLOCK,
355 ShareAccess: ULONG,
356 CreateDisposition: ULONG,
357 CreateOptions: ULONG,
358 NamedPipeType: ULONG,
359 ReadMode: ULONG,
360 CompletionMode: ULONG,
361 MaximumInstances: ULONG,
362 InboundQuota: ULONG,
363 OutboundQuota: ULONG,
364 DefaultTimeout: *LARGE_INTEGER,
365) callconv(.winapi) NTSTATUS;
366
367pub extern "ntdll" fn NtAllocateVirtualMemory(
368 ProcessHandle: HANDLE,
369 BaseAddress: ?*PVOID,
370 ZeroBits: ULONG_PTR,
371 RegionSize: ?*SIZE_T,
372 AllocationType: ULONG,
373 PageProtection: ULONG,
374) callconv(.winapi) NTSTATUS;
375
376pub extern "ntdll" fn NtFreeVirtualMemory(
377 ProcessHandle: HANDLE,
378 BaseAddress: ?*PVOID,
379 RegionSize: *SIZE_T,
380 FreeType: ULONG,
381) callconv(.winapi) NTSTATUS;
382461
383pub extern "ntdll" fn RtlAddVectoredExceptionHandler(462pub extern "ntdll" fn RtlAddVectoredExceptionHandler(
384 First: ULONG,463 First: ULONG,
...@@ -388,6 +467,29 @@ pub extern "ntdll" fn RtlRemoveVectoredExceptionHandler(...@@ -388,6 +467,29 @@ pub extern "ntdll" fn RtlRemoveVectoredExceptionHandler(
388 Handle: HANDLE,467 Handle: HANDLE,
389) callconv(.winapi) ULONG;468) callconv(.winapi) ULONG;
390469
470pub extern "ntdll" fn RtlDosPathNameToNtPathName_U(
471 DosPathName: [*:0]const u16,
472 NtPathName: *UNICODE_STRING,
473 NtFileNamePart: ?*?[*:0]const u16,
474 DirectoryInfo: ?*CURDIR,
475) callconv(.winapi) BOOL;
476
477pub extern "ntdll" fn RtlExitUserProcess(
478 ExitStatus: u32,
479) callconv(.winapi) noreturn;
480
481/// Returns the number of bytes written to `Buffer`.
482/// If the returned count is larger than `BufferByteLength`, the buffer was too small.
483/// If the returned count is zero, an error occurred.
484pub extern "ntdll" fn RtlGetFullPathName_U(
485 FileName: [*:0]const u16,
486 BufferByteLength: ULONG,
487 Buffer: [*]u16,
488 ShortName: ?*[*:0]const u16,
489) callconv(.winapi) ULONG;
490
491pub extern "ntdll" fn RtlGetSystemTimePrecise() callconv(.winapi) LARGE_INTEGER;
492
391pub extern "ntdll" fn RtlInitializeCriticalSection(493pub extern "ntdll" fn RtlInitializeCriticalSection(
392 lpCriticalSection: *CRITICAL_SECTION,494 lpCriticalSection: *CRITICAL_SECTION,
393) callconv(.winapi) NTSTATUS;495) callconv(.winapi) NTSTATUS;
...@@ -401,6 +503,28 @@ pub extern "ntdll" fn RtlDeleteCriticalSection(...@@ -401,6 +503,28 @@ pub extern "ntdll" fn RtlDeleteCriticalSection(
401 lpCriticalSection: *CRITICAL_SECTION,503 lpCriticalSection: *CRITICAL_SECTION,
402) callconv(.winapi) NTSTATUS;504) callconv(.winapi) NTSTATUS;
403505
506pub extern "ntdll" fn RtlQueryPerformanceCounter(
507 PerformanceCounter: *LARGE_INTEGER,
508) callconv(.winapi) BOOL;
509pub extern "ntdll" fn RtlQueryPerformanceFrequency(
510 PerformanceFrequency: *LARGE_INTEGER,
511) callconv(.winapi) BOOL;
512pub extern "ntdll" fn NtQueryPerformanceCounter(
513 PerformanceCounter: *LARGE_INTEGER,
514 PerformanceFrequency: ?*LARGE_INTEGER,
515) callconv(.winapi) NTSTATUS;
516
517pub extern "ntdll" fn RtlReAllocateHeap(
518 HeapHandle: *HEAP,
519 Flags: HEAP.FLAGS.ALLOCATION,
520 BaseAddress: ?PVOID,
521 Size: SIZE_T,
522) callconv(.winapi) ?PVOID;
523
524pub extern "ntdll" fn RtlSetCurrentDirectory_U(
525 PathName: *UNICODE_STRING,
526) callconv(.winapi) NTSTATUS;
527
404pub extern "ntdll" fn RtlTryAcquireSRWLockExclusive(528pub extern "ntdll" fn RtlTryAcquireSRWLockExclusive(
405 SRWLock: *SRWLOCK,529 SRWLock: *SRWLOCK,
406) callconv(.winapi) BOOLEAN;530) callconv(.winapi) BOOLEAN;
...@@ -411,21 +535,22 @@ pub extern "ntdll" fn RtlReleaseSRWLockExclusive(...@@ -411,21 +535,22 @@ pub extern "ntdll" fn RtlReleaseSRWLockExclusive(
411 SRWLock: *SRWLOCK,535 SRWLock: *SRWLOCK,
412) callconv(.winapi) void;536) callconv(.winapi) void;
413537
538pub extern "ntdll" fn RtlWakeAddressAll(
539 Address: ?*const anyopaque,
540) callconv(.winapi) void;
541pub extern "ntdll" fn RtlWakeAddressSingle(
542 Address: ?*const anyopaque,
543) callconv(.winapi) void;
544pub extern "ntdll" fn RtlWaitOnAddress(
545 Address: ?*const anyopaque,
546 CompareAddress: ?*const anyopaque,
547 AddressSize: SIZE_T,
548 Timeout: ?*const LARGE_INTEGER,
549) callconv(.winapi) NTSTATUS;
550
414pub extern "ntdll" fn RtlWakeConditionVariable(551pub extern "ntdll" fn RtlWakeConditionVariable(
415 ConditionVariable: *CONDITION_VARIABLE,552 ConditionVariable: *CONDITION_VARIABLE,
416) callconv(.winapi) void;553) callconv(.winapi) void;
417pub extern "ntdll" fn RtlWakeAllConditionVariable(554pub extern "ntdll" fn RtlWakeAllConditionVariable(
418 ConditionVariable: *CONDITION_VARIABLE,555 ConditionVariable: *CONDITION_VARIABLE,
419) callconv(.winapi) void;556) callconv(.winapi) void;
420
421pub extern "ntdll" fn RtlReAllocateHeap(
422 HeapHandle: HANDLE,
423 Flags: ULONG,
424 BaseAddress: PVOID,
425 Size: SIZE_T,
426) callconv(.winapi) ?PVOID;
427pub extern "ntdll" fn RtlAllocateHeap(
428 HeapHandle: HANDLE,
429 Flags: ULONG,
430 Size: SIZE_T,
431) callconv(.winapi) ?PVOID;
lib/std/posix.zig+8-7
...@@ -1041,18 +1041,16 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {...@@ -1041,18 +1041,16 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
10411041
1042 if (native_os == .windows) {1042 if (native_os == .windows) {
1043 var io_status_block: windows.IO_STATUS_BLOCK = undefined;1043 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
1044 var eof_info = windows.FILE_END_OF_FILE_INFORMATION{1044 const eof_info: windows.FILE.END_OF_FILE_INFORMATION = .{
1045 .EndOfFile = signed_len,1045 .EndOfFile = signed_len,
1046 };1046 };
1047
1048 const rc = windows.ntdll.NtSetInformationFile(1047 const rc = windows.ntdll.NtSetInformationFile(
1049 fd,1048 fd,
1050 &io_status_block,1049 &io_status_block,
1051 &eof_info,1050 &eof_info,
1052 @sizeOf(windows.FILE_END_OF_FILE_INFORMATION),1051 @sizeOf(windows.FILE.END_OF_FILE_INFORMATION),
1053 .FileEndOfFileInformation,1052 .EndOfFile,
1054 );1053 );
1055
1056 switch (rc) {1054 switch (rc) {
1057 .SUCCESS => return,1055 .SUCCESS => return,
1058 .INVALID_HANDLE => unreachable, // Handle not open for writing1056 .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 {...@@ -2691,8 +2689,11 @@ pub fn mkdirW(dir_path_w: []const u16, mode: mode_t) MakeDirError!void {
2691 _ = mode;2689 _ = mode;
2692 const sub_dir_handle = windows.OpenFile(dir_path_w, .{2690 const sub_dir_handle = windows.OpenFile(dir_path_w, .{
2693 .dir = fs.cwd().fd,2691 .dir = fs.cwd().fd,
2694 .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE,2692 .access_mask = .{
2695 .creation = windows.FILE_CREATE,2693 .STANDARD = .{ .SYNCHRONIZE = true },
2694 .GENERIC = .{ .READ = true },
2695 },
2696 .creation = .CREATE,
2696 .filter = .dir_only,2697 .filter = .dir_only,
2697 }) catch |err| switch (err) {2698 }) catch |err| switch (err) {
2698 error.IsDir => return error.Unexpected,2699 error.IsDir => return error.Unexpected,
lib/std/process/Child.zig+9-7
...@@ -762,10 +762,12 @@ fn spawnWindows(self: *ChildProcess) SpawnError!void {...@@ -762,10 +762,12 @@ fn spawnWindows(self: *ChildProcess) SpawnError!void {
762 const nul_handle = if (any_ignore)762 const nul_handle = if (any_ignore)
763 // "\Device\Null" or "\??\NUL"763 // "\Device\Null" or "\??\NUL"
764 windows.OpenFile(&[_]u16{ '\\', 'D', 'e', 'v', 'i', 'c', 'e', '\\', 'N', 'u', 'l', 'l' }, .{764 windows.OpenFile(&[_]u16{ '\\', 'D', 'e', 'v', 'i', 'c', 'e', '\\', 'N', 'u', 'l', 'l' }, .{
765 .access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE | windows.SYNCHRONIZE,765 .access_mask = .{
766 .share_access = windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE | windows.FILE_SHARE_DELETE,766 .STANDARD = .{ .SYNCHRONIZE = true },
767 .GENERIC = .{ .WRITE = true, .READ = true },
768 },
767 .sa = &saAttr,769 .sa = &saAttr,
768 .creation = windows.OPEN_EXISTING,770 .creation = .OPEN,
769 }) catch |err| switch (err) {771 }) catch |err| switch (err) {
770 error.PathAlreadyExists => return error.Unexpected, // not possible for "NUL"772 error.PathAlreadyExists => return error.Unexpected, // not possible for "NUL"
771 error.PipeBusy => return error.Unexpected, // not possible for "NUL"773 error.PipeBusy => return error.Unexpected, // not possible for "NUL"
...@@ -1174,7 +1176,7 @@ fn windowsCreateProcessPathExt(...@@ -1174,7 +1176,7 @@ fn windowsCreateProcessPathExt(
1174 &io_status,1176 &io_status,
1175 &file_information_buf,1177 &file_information_buf,
1176 file_information_buf.len,1178 file_information_buf.len,
1177 .FileDirectoryInformation,1179 .Directory,
1178 windows.FALSE, // single result1180 windows.FALSE, // single result
1179 &app_name_unicode_string,1181 &app_name_unicode_string,
1180 windows.FALSE, // restart iteration1182 windows.FALSE, // restart iteration
...@@ -1198,7 +1200,7 @@ fn windowsCreateProcessPathExt(...@@ -1198,7 +1200,7 @@ fn windowsCreateProcessPathExt(
1198 var it = windows.FileInformationIterator(windows.FILE_DIRECTORY_INFORMATION){ .buf = &file_information_buf };1200 var it = windows.FileInformationIterator(windows.FILE_DIRECTORY_INFORMATION){ .buf = &file_information_buf };
1199 while (it.next()) |info| {1201 while (it.next()) |info| {
1200 // Skip directories1202 // Skip directories
1201 if (info.FileAttributes & windows.FILE_ATTRIBUTE_DIRECTORY != 0) continue;1203 if (info.FileAttributes.DIRECTORY) continue;
1202 const filename = @as([*]u16, @ptrCast(&info.FileName))[0 .. info.FileNameLength / 2];1204 const filename = @as([*]u16, @ptrCast(&info.FileName))[0 .. info.FileNameLength / 2];
1203 // Because all results start with the app_name since we're using the wildcard `app_name*`,1205 // Because all results start with the app_name since we're using the wildcard `app_name*`,
1204 // if the length is equal to app_name then this is an exact match1206 // 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...@@ -1415,11 +1417,11 @@ fn windowsMakeAsyncPipe(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *cons
1415 var sattr_copy = sattr.*;1417 var sattr_copy = sattr.*;
1416 const write_handle = windows.kernel32.CreateFileW(1418 const write_handle = windows.kernel32.CreateFileW(
1417 pipe_path.ptr,1419 pipe_path.ptr,
1418 windows.GENERIC_WRITE,1420 .{ .GENERIC = .{ .WRITE = true } },
1419 0,1421 0,
1420 &sattr_copy,1422 &sattr_copy,
1421 windows.OPEN_EXISTING,1423 windows.OPEN_EXISTING,
1422 windows.FILE_ATTRIBUTE_NORMAL,1424 @bitCast(windows.FILE.ATTRIBUTE{ .NORMAL = true }),
1423 null,1425 null,
1424 );1426 );
1425 if (write_handle == windows.INVALID_HANDLE_VALUE) {1427 if (write_handle == windows.INVALID_HANDLE_VALUE) {
lib/std/zig/WindowsSdk.zig+9-4
...@@ -250,13 +250,15 @@ const RegistryWtf16Le = struct {...@@ -250,13 +250,15 @@ const RegistryWtf16Le = struct {
250 /// After finishing work, call `closeKey`.250 /// After finishing work, call `closeKey`.
251 fn openKey(hkey: windows.HKEY, key_wtf16le: [:0]const u16, options: OpenOptions) error{KeyNotFound}!RegistryWtf16Le {251 fn openKey(hkey: windows.HKEY, key_wtf16le: [:0]const u16, options: OpenOptions) error{KeyNotFound}!RegistryWtf16Le {
252 var key: windows.HKEY = undefined;252 var key: windows.HKEY = undefined;
253 var access: windows.REGSAM = windows.KEY_QUERY_VALUE | windows.KEY_ENUMERATE_SUB_KEYS;
254 if (options.wow64_32) access |= windows.KEY_WOW64_32KEY;
255 const return_code_int: windows.HRESULT = windows.advapi32.RegOpenKeyExW(253 const return_code_int: windows.HRESULT = windows.advapi32.RegOpenKeyExW(
256 hkey,254 hkey,
257 key_wtf16le,255 key_wtf16le,
258 0,256 0,
259 access,257 .{ .SPECIFIC = .{ .KEY = .{
258 .QUERY_VALUE = true,
259 .ENUMERATE_SUB_KEYS = true,
260 .WOW64_32KEY = options.wow64_32,
261 } } },
260 &key,262 &key,
261 );263 );
262 const return_code: windows.Win32Error = @enumFromInt(return_code_int);264 const return_code: windows.Win32Error = @enumFromInt(return_code_int);
...@@ -389,7 +391,10 @@ const RegistryWtf16Le = struct {...@@ -389,7 +391,10 @@ const RegistryWtf16Le = struct {
389 const return_code_int: windows.HRESULT = std.os.windows.advapi32.RegLoadAppKeyW(391 const return_code_int: windows.HRESULT = std.os.windows.advapi32.RegLoadAppKeyW(
390 absolute_path_as_wtf16le,392 absolute_path_as_wtf16le,
391 &key,393 &key,
392 windows.KEY_QUERY_VALUE | windows.KEY_ENUMERATE_SUB_KEYS,394 .{ .SPECIFIC = .{ .KEY = .{
395 .QUERY_VALUE = true,
396 .ENUMERATE_SUB_KEYS = true,
397 } } },
393 0,398 0,
394 0,399 0,
395 );400 );
src/link/MappedFile.zig+14-7
...@@ -953,12 +953,19 @@ pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void {...@@ -953,12 +953,19 @@ pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void {
953 if (is_windows) {953 if (is_windows) {
954 if (mf.section == windows.INVALID_HANDLE_VALUE) switch (windows.ntdll.NtCreateSection(954 if (mf.section == windows.INVALID_HANDLE_VALUE) switch (windows.ntdll.NtCreateSection(
955 &mf.section,955 &mf.section,
956 windows.STANDARD_RIGHTS_REQUIRED | windows.SECTION_QUERY |956 .{
957 windows.SECTION_MAP_WRITE | windows.SECTION_MAP_READ | windows.SECTION_EXTEND_SIZE,957 .SPECIFIC = .{ .SECTION = .{
958 .QUERY = true,
959 .MAP_WRITE = true,
960 .MAP_READ = true,
961 .EXTEND_SIZE = true,
962 } },
963 .STANDARD = .{ .RIGHTS = .REQUIRED },
964 },
958 null,965 null,
959 @constCast(&@as(i64, @intCast(aligned_capacity))),966 @constCast(&@as(i64, @intCast(aligned_capacity))),
960 windows.PAGE_READWRITE,967 .{ .READWRITE = true },
961 windows.SEC_COMMIT,968 .{ .COMMIT = true },
962 mf.file.handle,969 mf.file.handle,
963 )) {970 )) {
964 .SUCCESS => {},971 .SUCCESS => {},
...@@ -974,9 +981,9 @@ pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void {...@@ -974,9 +981,9 @@ pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void {
974 0,981 0,
975 null,982 null,
976 &contents_len,983 &contents_len,
977 .ViewUnmap,984 .Unmap,
978 0,985 .{},
979 windows.PAGE_READWRITE,986 .{ .READWRITE = true },
980 )) {987 )) {
981 .SUCCESS => mf.contents = contents_ptr.?[0..contents_len],988 .SUCCESS => mf.contents = contents_ptr.?[0..contents_len],
982 else => return error.MemoryMappingNotSupported,989 else => return error.MemoryMappingNotSupported,