//! This file contains thin wrappers around Windows-specific APIs, with these //! specific goals in mind: //! * Convert "errno"-style error codes into Zig errors. //! * When null-terminated or WTF16LE byte buffers are required, provide APIs which accept //! slices as well as APIs which accept null-terminated WTF16LE byte buffers. const builtin = @import("builtin"); const native_arch = builtin.cpu.arch; const std = @import("../std.zig"); const Io = std.Io; const mem = std.mem; const assert = std.debug.assert; const math = std.math; const maxInt = std.math.maxInt; const UnexpectedError = std.posix.UnexpectedError; pub const kernel32 = @import("windows/kernel32.zig"); pub const ntdll = @import("windows/ntdll.zig"); pub const ws2_32 = @import("windows/ws2_32.zig"); pub const crypt32 = @import("windows/crypt32.zig"); pub const nls = @import("windows/nls.zig"); pub const current_process: HANDLE = @ptrFromInt(@as(usize, @bitCast(@as(isize, -1)))); pub const PS = struct { pub const ATTRIBUTE = extern struct { Attribute: Type, Size: SIZE_T, u: extern union { Value: ULONG_PTR, ValuePtr: PVOID, }, ReturnLength: ?*SIZE_T, /// https://ntdoc.m417z.com/ps_attribute_num /// Tag type is `u16` based on PS_ATTRIBUTE_NUMBER_MASK being 0xFFFF pub const NUM = enum(u16) { ParentProcess = 0, DebugObject, Token, ClientId, TebAddress, ImageName, ImageInfo, MemoryReserve, PriorityClass, ErrorMode, StdHandleInfo, HandleList, GroupAffinity, PreferredNode, IdealProcessor, UmsThread, MitigationOptions, ProtectionLevel, SecureProcess, JobList, ChildProcessPolicy, AllApplicationPackagesPolicy, Win32kFilter, SafeOpenPromptOriginClaim, BnoIsolation, DesktopAppPolicy, Chpe, MitigationAuditOptions, MachineType, ComponentFilter, EnableOptionalXStateFeatures, SupportedMachines, SveVectorLength, }; /// https://ntdoc.m417z.com/psattributevalue pub const Type = enum(ULONG_PTR) { TEB_ADDRESS = construct(.TebAddress, true, false, false), _, pub fn construct(num: NUM, thread: bool, input: bool, additive: bool) ULONG_PTR { var val: ULONG_PTR = @intFromEnum(num); if (thread) val |= 0x10000; if (input) val |= 0x20000; if (additive) val |= 0x40000; return val; } }; pub const LIST = extern struct { TotalLength: SIZE_T, Attributes: [1]ATTRIBUTE, }; }; }; pub const OBJECT = struct { // ref: um/winternl.h pub const ATTRIBUTES = extern struct { Length: ULONG = @sizeOf(ATTRIBUTES), RootDirectory: ?HANDLE = null, ObjectName: ?*UNICODE_STRING = @constCast(&UNICODE_STRING.empty), Attributes: Flags = .{}, SecurityDescriptor: ?*anyopaque = null, SecurityQualityOfService: ?*anyopaque = null, // Valid values for the Attributes field pub const Flags = packed struct(ULONG) { Reserved0: u1 = 0, INHERIT: bool = false, Reserved2: u2 = 0, PERMANENT: bool = false, EXCLUSIVE: bool = false, /// If name-lookup code should ignore the case of the ObjectName member rather than performing an exact-match search. CASE_INSENSITIVE: bool = true, OPENIF: bool = false, OPENLINK: bool = false, KERNEL_HANDLE: bool = false, FORCE_ACCESS_CHECK: bool = false, IGNORE_IMPERSONATED_DEVICEMAP: bool = false, DONT_REPARSE: bool = false, Reserved13: u19 = 0, pub const VALID_ATTRIBUTES: ATTRIBUTES = .{ .INHERIT = true, .PERMANENT = true, .EXCLUSIVE = true, .CASE_INSENSITIVE = true, .OPENIF = true, .OPENLINK = true, .KERNEL_HANDLE = true, .FORCE_ACCESS_CHECK = true, .IGNORE_IMPERSONATED_DEVICEMAP = true, .DONT_REPARSE = true, }; }; }; pub const INFORMATION_CLASS = enum(c_int) { Basic = 0, Name = 1, Type = 2, Types = 3, HandleFlag = 4, Session = 5, _, pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".fields.len; }; pub const NAME_INFORMATION = extern struct { Name: UNICODE_STRING, }; }; pub const FILE = struct { // ref: km/ntddk.h pub const END_OF_FILE_INFORMATION = extern struct { EndOfFile: LARGE_INTEGER, }; pub const ALIGNMENT_INFORMATION = extern struct { AlignmentRequirement: ULONG, }; pub const NAME_INFORMATION = extern struct { FileNameLength: ULONG, FileName: [1]WCHAR, }; pub const DISPOSITION = packed struct(ULONG) { DELETE: bool = false, POSIX_SEMANTICS: bool = false, FORCE_IMAGE_SECTION_CHECK: bool = false, ON_CLOSE: bool = false, IGNORE_READONLY_ATTRIBUTE: bool = false, Reserved5: u27 = 0, pub const DO_NOT_DELETE: DISPOSITION = .{}; pub const INFORMATION = extern struct { DeleteFile: BOOLEAN, pub const EX = extern struct { Flags: DISPOSITION, }; }; }; pub const FS_VOLUME_INFORMATION = extern struct { VolumeCreationTime: LARGE_INTEGER, VolumeSerialNumber: ULONG, VolumeLabelLength: ULONG, SupportsObjects: BOOLEAN, VolumeLabel: [0]WCHAR, pub fn getVolumeLabel(fvi: *const FS_VOLUME_INFORMATION) []const WCHAR { return (&fvi).ptr[0..@divExact(fvi.VolumeLabelLength, @sizeOf(WCHAR))]; } }; // ref: km/ntifs.h pub const NAME_FLAGS = packed struct(UCHAR) { NTFS: bool = false, DOS: bool = false, Reserved2: u5 = 0, UNSPECIFIED: bool = false, }; pub const NOTIFY = struct { pub const CHANGE = packed struct(ULONG) { FILE_NAME: bool = false, DIR_NAME: bool = false, ATTRIBUTES: bool = false, SIZE: bool = false, LAST_WRITE: bool = false, LAST_ACCESS: bool = false, CREATION: bool = false, EA: bool = false, SECURITY: bool = false, STREAM_NAME: bool = false, STREAM_SIZE: bool = false, STREAM_WRITE: bool = false, Reserved12: u20 = 0, }; pub const INFORMATION = extern struct { NextEntryOffset: ULONG, Action: ULONG, FileNameLength: ULONG, FileName: [0]WCHAR, pub fn fileName(info: *INFORMATION) []WCHAR { const ptr: [*]WCHAR = @ptrCast(&info.FileName); return ptr[0..@divExact(info.FileNameLength, @sizeOf(WCHAR))]; } }; pub const EXTENDED_INFORMATION = extern struct { NextEntryOffset: ULONG, Action: ULONG, CreationTime: LARGE_INTEGER, LastModificationTime: LARGE_INTEGER, LastChangeTime: LARGE_INTEGER, LastAccessTime: LARGE_INTEGER, AllocatedLength: LARGE_INTEGER, FileSize: LARGE_INTEGER, FileAttributes: ATTRIBUTE, u: extern union { ReparsePointTag: ULONG, EaSize: ULONG, }, FileId: LARGE_INTEGER, ParentFileId: LARGE_INTEGER, FileNameLength: ULONG, FileName: [0]WCHAR, pub fn fileName(info: *INFORMATION) []WCHAR { const ptr: [*]WCHAR = @ptrCast(&info.FileName); return ptr[0..@divExact(info.FileNameLength, @sizeOf(WCHAR))]; } }; pub const FULL_INFORMATION = extern struct { NextEntryOffset: ULONG, Action: ULONG, CreationTime: LARGE_INTEGER, LastModificationTime: LARGE_INTEGER, LastChangeTime: LARGE_INTEGER, LastAccessTime: LARGE_INTEGER, AllocatedLength: LARGE_INTEGER, FileSize: LARGE_INTEGER, FileAttributes: ATTRIBUTE, u: extern union { ReparsePointTag: ULONG, EaSize: ULONG, }, FileId: LARGE_INTEGER, ParentFileId: LARGE_INTEGER, FileNameLength: ULONG, FileNameFlags: NAME_FLAGS, FileName: [0]WCHAR, pub fn fileName(info: *INFORMATION) []WCHAR { const ptr: [*]WCHAR = @ptrCast(&info.FileName); return ptr[0..@divExact(info.FileNameLength, @sizeOf(WCHAR))]; } }; }; pub const PIPE = struct { /// Define the `NamedPipeType` flags for `NtCreateNamedPipeFile` pub const TYPE = packed struct(ULONG) { TYPE: enum(u1) { BYTE_STREAM = 0b0, MESSAGE = 0b1, } = .BYTE_STREAM, REMOTE_CLIENTS: enum(u1) { ACCEPT = 0b0, REJECT = 0b1, } = .ACCEPT, Reserved2: u30 = 0, pub const VALID_MASK: TYPE = .{ .TYPE = .MESSAGE, .REMOTE_CLIENTS = .REJECT, }; }; /// Define the `CompletionMode` flags for `NtCreateNamedPipeFile` pub const COMPLETION_MODE = packed struct(ULONG) { OPERATION: enum(u1) { QUEUE = 0b0, COMPLETE = 0b1, } = .QUEUE, Reserved1: u31 = 0, }; /// Define the `ReadMode` flags for `NtCreateNamedPipeFile` pub const READ_MODE = packed struct(ULONG) { MODE: enum(u1) { BYTE_STREAM = 0b0, MESSAGE = 0b1, }, Reserved1: u31 = 0, }; /// Define the `NamedPipeConfiguration` flags for `NtQueryInformationFile` pub const CONFIGURATION = enum(ULONG) { INBOUND = 0x00000000, OUTBOUND = 0x00000001, FULL_DUPLEX = 0x00000002, }; /// Define the `NamedPipeState` flags for `NtQueryInformationFile` pub const STATE = enum(ULONG) { DISCONNECTED = 0x00000001, LISTENING = 0x00000002, CONNECTED = 0x00000003, CLOSING = 0x00000004, }; /// Define the `NamedPipeEnd` flags for `NtQueryInformationFile` pub const END = enum(ULONG) { CLIENT = 0x00000000, SERVER = 0x00000001, }; pub const INFORMATION = extern struct { ReadMode: READ_MODE, CompletionMode: COMPLETION_MODE, }; pub const LOCAL_INFORMATION = extern struct { NamedPipeType: TYPE, NamedPipeConfiguration: CONFIGURATION, MaximumInstances: ULONG, CurrentInstances: ULONG, InboundQuota: ULONG, ReadDataAvailable: ULONG, OutboundQuota: ULONG, WriteQuotaAvailable: ULONG, NamedPipeState: STATE, NamedPipeEnd: END, }; pub const REMOTE_INFORMATION = extern struct { CollectDataTime: LARGE_INTEGER, MaximumCollectionCount: ULONG, }; pub const WAIT_FOR_BUFFER = extern struct { Timeout: LARGE_INTEGER, NameLength: ULONG, TimeoutSpecified: BOOLEAN, Name: [PATH_MAX_WIDE]WCHAR, pub const WAIT_FOREVER: LARGE_INTEGER = std.math.minInt(LARGE_INTEGER); pub fn init(opts: struct { Timeout: ?LARGE_INTEGER = null, Name: []const WCHAR, }) WAIT_FOR_BUFFER { var fpwfb: WAIT_FOR_BUFFER = .{ .Timeout = opts.Timeout orelse undefined, .NameLength = @intCast(@sizeOf(WCHAR) * opts.Name.len), .TimeoutSpecified = @intFromBool(opts.Timeout != null), .Name = undefined, }; @memcpy(fpwfb.Name[0..opts.Name.len], opts.Name); return fpwfb; } pub fn getName(fpwfb: *const WAIT_FOR_BUFFER) []const WCHAR { return fpwfb.Name[0..@divExact(fpwfb.NameLength, @sizeOf(WCHAR))]; } pub fn toBuffer(fpwfb: *const WAIT_FOR_BUFFER) []const u8 { const start: [*]const u8 = @ptrCast(fpwfb); return start[0 .. @offsetOf(WAIT_FOR_BUFFER, "Name") + fpwfb.NameLength]; } }; }; pub const ALL_INFORMATION = extern struct { BasicInformation: BASIC_INFORMATION, StandardInformation: STANDARD_INFORMATION, InternalInformation: INTERNAL_INFORMATION, EaInformation: EA_INFORMATION, AccessInformation: ACCESS_INFORMATION, PositionInformation: POSITION_INFORMATION, ModeInformation: MODE.INFORMATION, AlignmentInformation: ALIGNMENT_INFORMATION, NameInformation: NAME_INFORMATION, }; pub const INTERNAL_INFORMATION = extern struct { IndexNumber: LARGE_INTEGER, }; pub const EA_INFORMATION = extern struct { EaSize: ULONG, }; pub const ACCESS_INFORMATION = extern struct { AccessFlags: ACCESS_MASK, }; /// This is not separated into RENAME_INFORMATION and RENAME_INFORMATION_EX because /// the only difference is the `Flags` type (BOOLEAN before _EX, ULONG in the _EX), /// which doesn't affect the struct layout--the offset of RootDirectory is the same /// regardless. pub const RENAME_INFORMATION = extern struct { Flags: FLAGS, RootDirectory: ?HANDLE, FileNameLength: ULONG, FileName: [PATH_MAX_WIDE]WCHAR, pub fn init(opts: struct { Flags: FLAGS = .{}, RootDirectory: ?HANDLE = null, FileName: []const WCHAR, }) RENAME_INFORMATION { var fri: RENAME_INFORMATION = .{ .Flags = opts.Flags, .RootDirectory = opts.RootDirectory, .FileNameLength = @intCast(@sizeOf(WCHAR) * opts.FileName.len), .FileName = undefined, }; @memcpy(fri.FileName[0..opts.FileName.len], opts.FileName); return fri; } pub const FLAGS = packed struct(ULONG) { REPLACE_IF_EXISTS: bool = false, POSIX_SEMANTICS: bool = false, SUPPRESS_PIN_STATE_INHERITANCE: bool = false, SUPPRESS_STORAGE_RESERVE_INHERITANCE: bool = false, AVAILABLE_SPACE: enum(u2) { NO_PRESERVE = 0b00, NO_INCREASE = 0b01, NO_DECREASE = 0b10, PRESERVE = 0b11, } = .NO_PRESERVE, IGNORE_READONLY_ATTRIBUTE: bool = false, RESIZE_SR: enum(u2) { NO_FORCE = 0b00, FORCE_TARGET = 0b01, FORCE_SOURCE = 0b10, FORCE = 0b11, } = .NO_FORCE, Reserved9: u23 = 0, }; pub fn getFileName(ri: *const RENAME_INFORMATION) []const WCHAR { return ri.FileName[0..@divExact(ri.FileNameLength, @sizeOf(WCHAR))]; } pub fn toBuffer(fri: *RENAME_INFORMATION) []u8 { const start: [*]u8 = @ptrCast(fri); // The ABI size of the documented struct is 24 bytes, and attempting to use any size // less than that will trigger INFO_LENGTH_MISMATCH, so enforce a minimum in cases where, // for example, FileNameLength is 1 so only 22 bytes are technically needed. const size = @max(24, @offsetOf(RENAME_INFORMATION, "FileName") + fri.FileNameLength); return start[0..size]; } }; // ref: km/wdm.h pub const INFORMATION_CLASS = enum(c_int) { Directory = 1, FullDirectory = 2, BothDirectory = 3, Basic = 4, Standard = 5, Internal = 6, Ea = 7, Access = 8, Name = 9, Rename = 10, Link = 11, Names = 12, Disposition = 13, Position = 14, FullEa = 15, Mode = 16, Alignment = 17, All = 18, Allocation = 19, EndOfFile = 20, AlternateName = 21, Stream = 22, Pipe = 23, PipeLocal = 24, PipeRemote = 25, MailslotQuery = 26, MailslotSet = 27, Compression = 28, ObjectId = 29, Completion = 30, MoveCluster = 31, Quota = 32, ReparsePoint = 33, NetworkOpen = 34, AttributeTag = 35, Tracking = 36, IdBothDirectory = 37, IdFullDirectory = 38, ValidDataLength = 39, ShortName = 40, IoCompletionNotification = 41, IoStatusBlockRange = 42, IoPriorityHint = 43, SfioReserve = 44, SfioVolume = 45, HardLink = 46, ProcessIdsUsingFile = 47, NormalizedName = 48, NetworkPhysicalName = 49, IdGlobalTxDirectory = 50, IsRemoteDevice = 51, Unused = 52, NumaNode = 53, StandardLink = 54, RemoteProtocol = 55, RenameBypassAccessCheck = 56, LinkBypassAccessCheck = 57, VolumeName = 58, Id = 59, IdExtdDirectory = 60, ReplaceCompletion = 61, HardLinkFullId = 62, IdExtdBothDirectory = 63, DispositionEx = 64, RenameEx = 65, RenameExBypassAccessCheck = 66, DesiredStorageClass = 67, Stat = 68, MemoryPartition = 69, StatLx = 70, CaseSensitive = 71, LinkEx = 72, LinkExBypassAccessCheck = 73, StorageReserveId = 74, CaseSensitiveForceAccessCheck = 75, KnownFolder = 76, StatBasic = 77, Id64ExtdDirectory = 78, Id64ExtdBothDirectory = 79, IdAllExtdDirectory = 80, IdAllExtdBothDirectory = 81, StreamReservation = 82, MupProvider = 83, _, pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".fields.len; }; pub const BASIC_INFORMATION = extern struct { CreationTime: LARGE_INTEGER, LastAccessTime: LARGE_INTEGER, LastWriteTime: LARGE_INTEGER, ChangeTime: LARGE_INTEGER, FileAttributes: ATTRIBUTE, }; pub const STANDARD_INFORMATION = extern struct { AllocationSize: LARGE_INTEGER, EndOfFile: LARGE_INTEGER, NumberOfLinks: ULONG, DeletePending: BOOLEAN, Directory: BOOLEAN, }; pub const POSITION_INFORMATION = extern struct { CurrentByteOffset: LARGE_INTEGER, }; pub const FULL_EA_INFORMATION = extern struct { NextEntryOffset: ULONG, Flags: UCHAR, EaNameLength: UCHAR, EaValueLength: USHORT, EaName: [0]CHAR, }; pub const FS_DEVICE_INFORMATION = extern struct { DeviceType: DEVICE_TYPE, Characteristics: ULONG, }; pub const USE_FILE_POINTER_POSITION = -2; // ref: um/WinBase.h pub const ATTRIBUTE_TAG_INFO = extern struct { FileAttributes: DWORD, ReparseTag: IO_REPARSE_TAG, }; // ref: um/winnt.h pub const SHARE = packed struct(ULONG) { /// The file can be opened for read access by other threads. READ: bool = false, /// The file can be opened for write access by other threads. WRITE: bool = false, /// The file can be opened for delete access by other threads. DELETE: bool = false, Reserved3: u29 = 0, pub const VALID_FLAGS: SHARE = .{ .READ = true, .WRITE = true, .DELETE = true, }; }; pub const ATTRIBUTE = packed struct(ULONG) { /// The file is read only. Applications can read the file, but cannot write to or delete it. READONLY: bool = false, /// The file is hidden. Do not include it in an ordinary directory listing. HIDDEN: bool = false, /// The file is part of or used exclusively by an operating system. SYSTEM: bool = false, Reserved3: u1 = 0, DIRECTORY: bool = false, /// The file should be archived. Applications use this attribute to mark files for backup or removal. ARCHIVE: bool = false, DEVICE: bool = false, /// The file does not have other attributes set. This attribute is valid only if used alone. NORMAL: bool = false, /// The file is being used for temporary storage. TEMPORARY: bool = false, SPARSE_FILE: bool = false, REPARSE_POINT: bool = false, COMPRESSED: bool = false, /// The data of a file is not immediately available. This attribute indicates that file data is physically moved to offline storage. /// This attribute is used by Remote Storage, the hierarchical storage management software. Applications should not arbitrarily change this attribute. OFFLINE: bool = false, NOT_CONTENT_INDEXED: bool = false, /// The file or directory is encrypted. For a file, this means that all data in the file is encrypted. For a directory, this means that encryption is /// the default for newly created files and subdirectories. For more information, see File Encryption. /// /// This flag has no effect if `SYSTEM` is also specified. /// /// This flag is not supported on Home, Home Premium, Starter, or ARM editions of Windows. ENCRYPTED: bool = false, INTEGRITY_STREAM: bool = false, VIRTUAL: bool = false, NO_SCRUB_DATA: bool = false, EA_or_RECALL_ON_OPEN: bool = false, PINNED: bool = false, UNPINNED: bool = false, Reserved21: u1 = 0, RECALL_ON_DATA_ACCESS: bool = false, Reserved23: u6 = 0, STRICTLY_SEQUENTIAL: bool = false, Reserved30: u2 = 0, }; // ref: um/winternl.h /// Define the create disposition values pub const CREATE_DISPOSITION = enum(ULONG) { /// If the file already exists, replace it with the given file. If it does not, create the given file. SUPERSEDE = 0x00000000, /// If the file already exists, open it instead of creating a new file. /// If it does not, fail the request and do not create a new file. OPEN = 0x00000001, /// If the file already exists, fail the request and do not create or /// open the given file. If it does not, create the given file. CREATE = 0x00000002, /// If the file already exists, open it. If it does not, create the given file. OPEN_IF = 0x00000003, /// If the file already exists, open it and overwrite it. If it does not, fail the request. OVERWRITE = 0x00000004, /// If the file already exists, open it and overwrite it. If it does not, create the given file. OVERWRITE_IF = 0x00000005, pub const MAXIMUM_DISPOSITION: CREATE_DISPOSITION = .OVERWRITE_IF; }; /// Define the create/open option flags pub const MODE = packed struct(ULONG) { /// The file being created or opened is a directory file. With this /// flag, the CreateDisposition parameter must be set to `.CREATE`, /// `.FILE_OPEN`, or `.OPEN_IF`. With this flag, other compatible /// CreateOptions flags include only the following: `SYNCHRONOUS_IO`, /// `WRITE_THROUGH`, `OPEN_FOR_BACKUP_INTENT`, and `OPEN_BY_FILE_ID`. DIRECTORY_FILE: bool = false, /// Applications that write data to the file must actually transfer the /// data into the file before any requested write operation is /// considered complete. This flag is automatically set if the /// CreateOptions flag `NO_INTERMEDIATE_BUFFERING` is set. WRITE_THROUGH: bool = false, /// All accesses to the file are sequential. SEQUENTIAL_ONLY: bool = false, /// The file cannot be cached or buffered in a driver's internal /// buffers. This flag is incompatible with the DesiredAccess /// `FILE_APPEND_DATA` flag. NO_INTERMEDIATE_BUFFERING: bool = false, IO: enum(u2) { /// All operations on the file are performed asynchronously. ASYNCHRONOUS = 0b00, /// All operations on the file are performed synchronously. Any /// wait on behalf of the caller is subject to premature /// termination from alerts. This flag also causes the I/O system /// to maintain the file position context. If this flag is set, the /// DesiredAccess `SYNCHRONIZE` flag also must be set. SYNCHRONOUS_ALERT = 0b01, /// All operations on the file are performed synchronously. Waits /// in the system to synchronize I/O queuing and completion are not /// subject to alerts. This flag also causes the I/O system to /// maintain the file position context. If this flag is set, the /// DesiredAccess `SYNCHRONIZE` flag also must be set. SYNCHRONOUS_NONALERT = 0b10, _, pub const VALID_FLAGS: @This() = @enumFromInt(0b11); }, /// The file being opened must not be a directory file or this call /// fails. The file object being opened can represent a data file, a /// logical, virtual, or physical device, or a volume. NON_DIRECTORY_FILE: bool = false, /// Create a tree connection for this file in order to open it over the /// network. This flag is not used by device and intermediate drivers. CREATE_TREE_CONNECTION: bool = false, /// Complete this operation immediately with an alternate success code /// of `STATUS_OPLOCK_BREAK_IN_PROGRESS` if the target file is /// oplocked, rather than blocking the caller's thread. If the file is /// oplocked, another caller already has access to the file. This flag /// is not used by device and intermediate drivers. COMPLETE_IF_OPLOCKED: bool = false, /// If the extended attributes on an existing file being opened /// indicate that the caller must understand EAs to properly interpret /// the file, fail this request because the caller does not understand /// how to deal with EAs. This flag is irrelevant for device and /// intermediate drivers. NO_EA_KNOWLEDGE: bool = false, OPEN_REMOTE_INSTANCE: bool = false, /// Accesses to the file can be random, so no sequential read-ahead /// operations should be performed on the file by FSDs or the system. RANDOM_ACCESS: bool = false, /// Delete the file when the last handle to it is passed to `NtClose`. /// If this flag is set, the `DELETE` flag must be set in the /// DesiredAccess parameter. DELETE_ON_CLOSE: bool = false, /// The file name that is specified by the `ObjectAttributes` parameter /// includes the 8-byte file reference number for the file. This number /// is assigned by and specific to the particular file system. If the /// file is a reparse point, the file name will also include the name /// of a device. Note that the FAT file system does not support this /// flag. This flag is not used by device and intermediate drivers. OPEN_BY_FILE_ID: bool = false, /// The file is being opened for backup intent. Therefore, the system /// should check for certain access rights and grant the caller the /// appropriate access to the file before checking the DesiredAccess /// parameter against the file's security descriptor. This flag not /// used by device and intermediate drivers. OPEN_FOR_BACKUP_INTENT: bool = false, /// Suppress inheritance of `FILE_ATTRIBUTE.COMPRESSED` from the parent /// directory. This allows creation of a non-compressed file in a /// directory that is marked compressed. NO_COMPRESSION: bool = false, /// The file is being opened and an opportunistic lock on the file is /// being requested as a single atomic operation. The file system /// checks for oplocks before it performs the create operation and will /// fail the create with a return code of STATUS_CANNOT_BREAK_OPLOCK if /// the result would be to break an existing oplock. For more /// information, see the Remarks section. /// /// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows /// XP: This flag is not supported. /// /// This flag is supported on the following file systems: NTFS, FAT, /// and exFAT. OPEN_REQUIRING_OPLOCK: bool = false, Reserved17: u3 = 0, /// This flag allows an application to request a filter opportunistic /// lock to prevent other applications from getting share violations. /// If there are already open handles, the create request will fail /// with STATUS_OPLOCK_NOT_GRANTED. For more information, see the /// Remarks section. RESERVE_OPFILTER: bool = false, /// Open a file with a reparse point and bypass normal reparse point /// processing for the file. For more information, see the Remarks /// section. OPEN_REPARSE_POINT: bool = false, /// Instructs any filters that perform offline storage or /// virtualization to not recall the contents of the file as a result /// of this open. OPEN_NO_RECALL: bool = false, /// This flag instructs the file system to capture the user associated /// with the calling thread. Any subsequent calls to /// `FltQueryVolumeInformation` or `ZwQueryVolumeInformationFile` using /// the returned handle will assume the captured user, rather than the /// calling user at the time, for purposes of computing the free space /// available to the caller. This applies to the following /// FsInformationClass values: `FileFsSizeInformation`, /// `FileFsFullSizeInformation`, and `FileFsFullSizeInformationEx`. OPEN_FOR_FREE_SPACE_QUERY: bool = false, Reserved24: u8 = 0, pub const VALID_OPTION_FLAGS: MODE = .{ .DIRECTORY_FILE = true, .WRITE_THROUGH = true, .SEQUENTIAL_ONLY = true, .NO_INTERMEDIATE_BUFFERING = true, .IO = .VALID_FLAGS, .NON_DIRECTORY_FILE = true, .CREATE_TREE_CONNECTION = true, .COMPLETE_IF_OPLOCKED = true, .NO_EA_KNOWLEDGE = true, .OPEN_REMOTE_INSTANCE = true, .RANDOM_ACCESS = true, .DELETE_ON_CLOSE = true, .OPEN_BY_FILE_ID = true, .OPEN_FOR_BACKUP_INTENT = true, .NO_COMPRESSION = true, .OPEN_REQUIRING_OPLOCK = true, .Reserved17 = 0b111, .RESERVE_OPFILTER = true, .OPEN_REPARSE_POINT = true, .OPEN_NO_RECALL = true, .OPEN_FOR_FREE_SPACE_QUERY = true, }; pub const VALID_PIPE_OPTION_FLAGS: MODE = .{ .WRITE_THROUGH = true, .IO = .VALID_FLAGS, }; pub const VALID_MAILSLOT_OPTION_FLAGS: MODE = .{ .WRITE_THROUGH = true, .IO = .VALID_FLAGS, }; pub const VALID_SET_OPTION_FLAGS: MODE = .{ .WRITE_THROUGH = true, .SEQUENTIAL_ONLY = true, .IO = .VALID_FLAGS, }; // ref: km/ntifs.h pub const INFORMATION = extern struct { /// The set of flags that specify the mode in which the file can be /// accessed. These flags are a subset of `MODE`. Mode: MODE, }; }; }; pub const DIRECTORY = struct { pub const NOTIFY_INFORMATION_CLASS = enum(c_int) { Notify = 1, NotifyExtended = 2, NotifyFull = 3, _, pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".fields.len; }; }; pub const CONSOLE = struct { pub const USER_IO = struct { pub const INFO = struct { pub const CP = extern struct { /// GetCP: output /// SetCP: input CodePage: UINT, /// input Mode: MODE, pub const MODE = enum(BOOLEAN.Backing) { Input, Output, }; }; pub const WRITE = extern struct { /// output, in bytes Size: DWORD, /// input Mode: MODE, pub const MODE = enum(BOOLEAN.Backing) { Character, WideCharacter, }; }; pub const FILL = extern struct { /// input dwWriteCoord: COORD, /// input Tag: WITH.Tag, /// input With: WITH.Payload, /// input/output, in characters nLength: DWORD, pub const WITH = union(enum(DWORD)) { Character: CHAR = 1, WideCharacter: WCHAR = 2, Attribute: WORD = 3, pub const Tag = @typeInfo(WITH).@"union".tag_type.?; pub const Payload = PAYLOAD: { const with_fields = @typeInfo(WITH).@"union".fields; var field_names: [with_fields.len][]const u8 = undefined; var field_types: [with_fields.len]type = undefined; for (with_fields, &field_names, &field_types) |field, *field_name, *field_type| { field_name.* = field.name; field_type.* = field.type; } break :PAYLOAD @Union(.@"extern", null, &field_names, &field_types, &@splat(.{})); }; }; }; /// all output pub const SCREEN_BUFFER = extern struct { dwSize: COORD, dwCursorPosition: COORD, dwWindowPosition: COORD, wAttributes: WORD, dwWindowSize: COORD, dwMaximumWindowSize: COORD, wPopupAttributes: WORD, bFullscreenSupported: BOOL, ColorTable: [16]COLORREF, }; pub const READ_OUTPUT_CHARACTER = extern struct { /// input dwReadCoord: COORD, Mode: MODE, /// output, in characters nLength: DWORD, pub const MODE = enum(DWORD) { Character = 1, WideCharacter = 2, }; }; }; pub fn GET_CP(mode: INFO.CP.MODE) Header.With(INFO.CP) { return .init(.GetCP, .{ .CodePage = undefined, .Mode = mode }); } pub const GET_MODE: Header.With(DWORD) = .init(.GetMode, undefined); pub fn SET_MODE(mode: DWORD) Header.With(DWORD) { return .init(.SetMode, mode); } pub fn WRITE(mode: INFO.WRITE.MODE) Header.With(INFO.WRITE) { return .init(.Write, .{ .Size = undefined, .Mode = mode }); } pub fn FILL(with: INFO.FILL.WITH, len: DWORD, coord: COORD) Header.With(INFO.FILL) { return .init(.Fill, .{ .dwWriteCoord = coord, .Tag = with, .With = switch (with) { inline else => |payload, tag| @unionInit( INFO.FILL.WITH.Payload, @tagName(tag), payload, ), }, .nLength = len, }); } pub fn SET_CP(mode: INFO.CP.MODE, cp: UINT) Header.With(INFO.CP) { return .init(.SetCP, .{ .CodePage = cp, .Mode = mode }); } pub const GET_SCREEN_BUFFER_INFO: Header.With(INFO.SCREEN_BUFFER) = .init(.GetScreenBufferInfo, undefined); pub fn SET_CURSOR_POSITION(coord: COORD) Header.With(COORD) { return .init(.SetCursorPosition, coord); } pub fn SET_TEXT_ATTRIBUTE(attribute: WORD) Header.With(WORD) { return .init(.SetTextAttribute, attribute); } pub fn READ_OUTPUT_CHARACTER( coord: COORD, mode: INFO.READ_OUTPUT_CHARACTER.MODE, ) Header.With(INFO.READ_OUTPUT_CHARACTER) { return .init(.ReadOutputCharacter, .{ .dwReadCoord = coord, .Mode = mode, .nLength = undefined, }); } pub const InputBuffer = extern struct { Size: u32, Pointer: *const anyopaque, }; pub const OutputBuffer = extern struct { Size: u32, Pointer: *anyopaque, }; pub fn Request(comptime in_len: u32, comptime out_len: u32) type { return extern struct { Handle: ?HANDLE, InputBuffersLength: u32, OutputBuffersLength: u32, InputBuffers: [in_len]InputBuffer, OutputBuffers: [out_len]OutputBuffer, pub fn init( handle: ?HANDLE, in: [in_len]InputBuffer, out: [out_len]OutputBuffer, ) @This() { return .{ .Handle = handle, .InputBuffersLength = in_len, .OutputBuffersLength = out_len, .InputBuffers = in, .OutputBuffers = out, }; } }; } pub const Header = extern struct { Operation: Operation, Size: u32, pub fn With(comptime Data: type) type { return extern struct { Header: Header, Data: Data, pub fn init(operation: Operation, data: Data) @This() { return .{ .Header = .{ .Operation = operation, .Size = @sizeOf(Data) }, .Data = data, }; } pub fn request( with: *@This(), file: ?Io.File, comptime in_len: u32, in: [in_len]InputBuffer, comptime out_len: u32, out: [out_len]OutputBuffer, ) Request(1 + in_len, 1 + out_len) { return .init( if (file) |f| f.handle else null, [1]InputBuffer{.{ .Size = @offsetOf(@This(), "Data") + @sizeOf(Data), .Pointer = with, }} ++ in, [1]OutputBuffer{.{ .Size = @sizeOf(Data), .Pointer = &with.Data }} ++ out, ); } pub fn operate(with: *@This(), io: Io, file: ?Io.File) Io.Cancelable!NTSTATUS { return (try io.operate(.{ .device_io_control = .{ .file = .{ .handle = peb().ProcessParameters.ConsoleHandle, .flags = .{ .nonblocking = false }, }, .code = IOCTL.CONDRV.ISSUE_USER_IO, .in = @ptrCast(&with.request(file, 0, .{}, 0, .{})), } })).device_io_control.u.Status; } }; } }; pub const Operation = enum(u32) { GetCP = 0x1000000, GetMode = 0x1000001, SetMode = 0x1000002, Read = 0x1000005, Write = 0x1000006, Fill = 0x2000000, SetCP = 0x2000004, GetScreenBufferInfo = 0x2000007, SetCursorPosition = 0x200000a, SetTextAttribute = 0x200000d, ReadOutputCharacter = 0x200000f, _, }; }; }; pub const AFD = packed struct(ULONG) { NO_FAST_IO: bool = false, OVERLAPPED: bool = false, Reserved0: u30 = 0, pub const Mutability = enum { @"const", @"var" }; pub fn WSABUF(comptime mutability: Mutability) type { return extern struct { len: ULONG, buf: switch (mutability) { .@"const" => [*]const u8, .@"var" => [*]u8, }, }; } pub const GUARANTEE = enum(c_int) { BestEffort, ControlledLoad, Predictive, GuaranteedDelay, Guaranteed, _, }; pub const DEVICE_NAME: []const u16 = &.{ '\\', 'D', 'e', 'v', 'i', 'c', 'e', '\\', 'A', 'f', 'd' }; pub const ENDPOINT_TYPE = packed struct(ULONG) { CONNECTIONLESS: bool = false, Reserved1: u3 = 0, MESSAGEMODE: bool = false, Reserved5: u3 = 0, RAW: bool = false, Reserved9: u22 = 0, REGISTERED_IO: bool = false, }; pub const OPEN_PACKET = extern struct { EndpointType: ENDPOINT_TYPE, GroupID: LONG, AddressFamily: LONG, SocketType: LONG, Protocol: LONG, TransportDeviceNameLength: ULONG, TransportDeviceName: [1]WCHAR, pub const NAME = "AfdOpenPacketXX"; pub const FULL_EA_INFORMATION = extern struct { Header: FILE.FULL_EA_INFORMATION = .{ .NextEntryOffset = 0, .Flags = 0, .EaNameLength = NAME.len, .EaValueLength = @sizeOf(OPEN_PACKET), .EaName = .{}, }, Name: [NAME.len:0]u8 = NAME.*, Value: OPEN_PACKET, }; }; pub const BIND_INFO = extern struct { Mode: MODE, pub const MODE = enum(ULONG) { Unix = 0, Passive = 1, Active = 2, _, }; }; pub const LISTEN_INFO = extern struct { UseSAN: BOOLEAN, MaximumConnectionQueue: ULONG, UseDelayedAcceptance: BOOLEAN, }; pub const LISTEN_RESPONSE_INFO = extern struct { Sequence: ULONG, }; pub const ACCEPT_INFO = extern struct { UseSAN: BOOLEAN, Sequence: ULONG, AcceptHandle: HANDLE, }; pub const SUPER_ACCEPT_INFO = extern struct { UseSAN: BOOLEAN, AcceptHandle: HANDLE, AcceptEndpoint: PVOID, AcceptFileObject: PVOID, ReceiveDataLength: ULONG, LocalAddressLength: ULONG, RemoteAddressLength: ULONG, ListenResponseInfo: LISTEN_RESPONSE_INFO, }; pub const DEFER_ACCEPT_INFO = extern struct { Sequence: ULONG, Reject: BOOLEAN, }; pub const PARTIAL_DISCONNECT_INFO = extern struct { DisconnectMode: MODE, Timeout: LARGE_INTEGER, pub const MODE = packed struct(ULONG) { SEND: bool = false, RECEIVE: bool = false, ABORTIVE: bool = false, UNCONNECT_DATAGRAM: bool = false, Reserved4: u28 = 0, }; }; pub const RECEIVE_INFORMATION = extern struct { BytesAvailable: ULONG, ExpeditedBytesAvailable: ULONG, }; pub const HANDLE_INFO = extern struct { TdiAddressHandle: HANDLE, TdiConnectionHandle: HANDLE, }; pub const INFORMATION = extern struct { InformationType: TYPE, Information: extern union { Boolean: BOOLEAN, Ulong: ULONG, LargeInteger: LARGE_INTEGER, }, pub const TYPE = enum(ULONG) { INLINE_MODE = 0x01, NONBLOCKING_MODE = 0x02, MAX_SEND_SIZE = 0x03, SENDS_PENDING = 0x04, MAX_PATH_SEND_SIZE = 0x05, RECEIVE_WINDOW_SIZE = 0x06, SEND_WINDOW_SIZE = 0x07, CONNECT_TIME = 0x08, CIRCULAR_QUEUEING = 0x09, GROUP_ID_AND_TYPE = 0x0A, _, }; }; pub const TRANSMIT_FILE_INFO = extern struct { Offset: LARGE_INTEGER, WriteLength: LARGE_INTEGER, SendPacketLength: ULONG, FileHandle: HANDLE, Head: PVOID, HeadLength: ULONG, Tail: PVOID, TailLength: ULONG, Flags: FLAGS, pub const FLAGS = packed struct(ULONG) { DISCONNECT: bool = false, REUSE_SOCKET: bool = false, WRITE_BEHIND: bool = false, Reserved3: u25 = 0, }; }; pub const QUEUE_APC_INFO = extern struct { Thread: HANDLE, ApcRoutine: PVOID, ApcContext: PVOID, SystemArgument1: PVOID, SystemArgument2: PVOID, }; pub const SEND_INFO = extern struct { BufferArray: [*]const WSABUF(.@"const"), BufferCount: ULONG, AfdFlags: AFD, TdiFlags: TDI.SEND, }; pub const SEND_DATAGRAM_INFO = extern struct { BufferArray: [*]const WSABUF(.@"const"), BufferCount: ULONG, AfdFlags: AFD, TdiRequest: TDI.REQUEST.SEND_DATAGRAM, TdiConnInfo: TDI.CONNECTION.INFORMATION, }; pub const RECV_INFO = extern struct { BufferArray: [*]const WSABUF(.@"var"), BufferCount: ULONG, AfdFlags: AFD, TdiFlags: TDI.RECEIVE, }; pub const RECV_DATAGRAM_INFO = extern struct { BufferArray: [*]const WSABUF(.@"var"), BufferCount: ULONG, AfdFlags: AFD, TdiFlags: TDI.RECEIVE, Address: PVOID, AddressLength: *ULONG, }; pub const SOCKOPT_INFO = extern struct { mode: Mode, level: i32, optname: u32, ding: u32 = 1, optval: *const anyopaque, optlen: usize, pub const Mode = enum(u32) { set = 1, get = 2, special = 3, _ }; pub const UNIX_PATH = extern struct { Unknown0: usize = 0, Path: [PATH_MAX_WIDE:0]u16 }; }; }; pub const TDI = struct { pub const STATUS = NTSTATUS; pub const CONNECTION = struct { pub const CONTEXT = PVOID; pub const INFORMATION = extern struct { /// length of user data buffer UserDataLength: LONG, /// pointer to user data buffer UserData: PVOID, /// length of following buffer OptionsLength: LONG, /// pointer to buffer containing options Options: PVOID, /// length of following buffer RemoteAddressLength: LONG, /// buffer containing the remote address RemoteAddress: PVOID, }; }; pub const ADDRESS = struct { pub const TYPE = enum(USHORT) { /// unspecified UNSPEC = 0, /// local to host (pipes, portals, UNIX = 1, /// internetwork: UDP, TCP, etc. IP = 2, /// arpanet imp addresses IMPLINK = 3, /// pup protocols: e.g. BSP PUP = 4, /// mit CHAOS protocols CHAOS = 5, /// XEROX NS protocols NS = 6, /// Netware IPX IPX = 6, /// nbs protocols NBS = 7, /// european computer manufacturers ECMA = 8, /// datakit protocols DATAKIT = 9, /// CCITT protocols, X.25 etc CCITT = 10, /// IBM SNA SNA = 11, /// DECnet DECnet = 12, /// Direct data link interface DLI = 13, /// LAT LAT = 14, /// NSC Hyperchannel HYLINK = 15, /// AppleTalk APPLETALK = 16, /// Netbios Addresses NETBIOS = 17, @"8022" = 18, OSI_TSAP = 19, /// for WzMail NETONE = 20, /// Banyan VINES IP VNS = 21, /// NETBIOS address extensions NETBIOS_EX = 22, /// IP version 6 IP6 = 23, /// WCHAR Netbios address NETBIOS_UNICODE_EX = 24, _, }; pub const IP = extern struct { sin_port: USHORT, in_addr: ULONG, sin_zero: [8]UCHAR, }; pub const IP6 = extern struct { sin_port: USHORT, flowinfo: ULONG, addr: [8]USHORT, scope_id: ULONG, }; }; pub const REQUEST = extern struct { Handle: extern union { AddressHandle: HANDLE, ConnectionContext: CONNECTION.CONTEXT, ControlChannel: HANDLE, }, RequestNotifyObject: PVOID, RequestContext: PVOID, TdiStatus: TDI.STATUS, pub const STATUS = extern struct { /// status of request completion Status: TDI.STATUS, /// the request context RequestContext: PVOID, /// number of bytes transferred in the request BytesTransferred: ULONG, }; pub const ASSOCIATE = extern struct { Request: REQUEST, AddressHandle: HANDLE, }; pub const CONNECT = extern struct { Request: REQUEST, RequestConnectionInformation: *CONNECTION.INFORMATION, ReturnConnectionInformation: *CONNECTION.INFORMATION, Timeout: LARGE_INTEGER, }; pub const ACCEPT = extern struct { Request: REQUEST, RequestConnectionInformation: *CONNECTION.INFORMATION, ReturnConnectionInformation: *CONNECTION.INFORMATION, }; pub const LISTEN = extern struct { Request: REQUEST, RequestConnectionInformation: *CONNECTION.INFORMATION, ReturnConnectionInformation: *CONNECTION.INFORMATION, ListenFlags: USHORT, }; pub const DISCONNECT = extern struct { Request: REQUEST, Timeout: LARGE_INTEGER, }; pub const SEND = extern struct { Request: REQUEST, SendFlags: USHORT, }; pub const RECEIVE = extern struct { Request: REQUEST, ReceiveFlags: USHORT, }; pub const SEND_DATAGRAM = extern struct { Request: REQUEST, SendDatagramInformation: *CONNECTION.INFORMATION, }; }; pub const RECEIVE = packed struct(ULONG) { Reserved0: u2 = 0, BROADCAST: bool = false, MULTICAST: bool = false, PARTIAL: bool = false, NORMAL: bool = false, EXPEDITED: bool = false, PEEK: bool = false, NO_RESPONSE_EXP: bool = false, COPY_LOOKAHEAD: bool = false, ENTIRE_MESSAGE: bool = false, AT_DISPATCH_LEVEL: bool = false, CONTROL_INFO: bool = false, FORCE_INDICATION: bool = false, NO_PUSH: bool = false, Reserved12: u17 = 0, }; pub const SEND = packed struct(ULONG) { Reserved0: u5 = 0, EXPEDITED: bool = false, PARTIAL: bool = false, NO_RESPONSE_EXPECTED: bool = false, NON_BLOCKING: bool = false, AND_DISCONNECT: bool = false, Reserved10: u22 = 0, }; }; pub const NET = struct { pub const LUID = packed struct(ULONG64) { Reserved: u24 = 0, Index: u24, IfType: u16 }; pub const IFINDEX = enum(ULONG) { _ }; }; pub const DNS = struct { pub const INTERFACE_SETTINGS = extern struct { Version: ULONG, Flags: ULONG64, Domain: PWSTR, NameServer: PWSTR, SearchList: PWSTR, RegistrationEnabled: ULONG, RegisterAdapterName: ULONG, EnableLLMNR: ULONG, QueryAdapterName: ULONG, ProfileNameServer: PWSTR, }; // ref: shared/windnsdef.h pub const ADDR_MAX_SOCKADDR_LENGTH = 32; pub const ADDR = extern struct { MaxSa: [ADDR_MAX_SOCKADDR_LENGTH]CHAR, DnsAddrUserDword: [8]DWORD, pub const ARRAY = extern struct { MaxCount: DWORD, AddrCount: DWORD, Tag: DWORD, Family: WORD, WordReserved: WORD, Flags: DWORD, MatchFlag: DWORD, Reserved1: DWORD, Reserved2: DWORD, AddrArray: [0]ADDR, }; }; pub const CUSTOM_SERVER = extern struct { ServerType: CUSTOM_SERVER.TYPE, Flags: FLAGS, Info: extern union { UDP: void, DOH: extern struct { Template: PWSTR }, DOT: extern struct { Hostname: PWSTR }, }, MaxSa: [ADDR_MAX_SOCKADDR_LENGTH]CHAR, pub const TYPE = enum(DWORD) { UDP = 0x1, DOH = 0x2, DOT = 0x3, _ }; pub const FLAGS = packed struct(ULONG64) { UDP_FALLBACK: bool = false, UPGRADE_FROM_WELL_KNOWN_SERVERS: bool = false, Reserved2: u62 = 0, }; }; // ref: um/WinDNS.h pub const STATUS = Win32Error; pub const TYPE = enum(WORD) { A = 0x0001, NS = 0x0002, MD = 0x0003, MF = 0x0004, CNAME = 0x0005, SOA = 0x0006, MB = 0x0007, MG = 0x0008, MR = 0x0009, NULL = 0x000a, WKS = 0x000b, PTR = 0x000c, HINFO = 0x000d, MINFO = 0x000e, MX = 0x000f, TEXT = 0x0010, RP = 0x0011, AFSDB = 0x0012, X25 = 0x0013, ISDN = 0x0014, RT = 0x0015, NSAP = 0x0016, NSAPPTR = 0x0017, SIG = 0x0018, KEY = 0x0019, PX = 0x001a, GPOS = 0x001b, AAAA = 0x001c, LOC = 0x001d, NXT = 0x001e, EID = 0x001f, NIMLOC = 0x0020, SRV = 0x0021, ATMA = 0x0022, NAPTR = 0x0023, KX = 0x0024, CERT = 0x0025, A6 = 0x0026, DNAME = 0x0027, SINK = 0x0028, OPT = 0x0029, DS = 0x002B, RRSIG = 0x002E, NSEC = 0x002F, DNSKEY = 0x0030, DHCID = 0x0031, UINFO = 0x0064, UID = 0x0065, GID = 0x0066, UNSPEC = 0x0067, ADDRS = 0x00f8, TKEY = 0x00f9, TSIG = 0x00fa, IXFR = 0x00fb, AXFR = 0x00fc, MAILB = 0x00fd, MAILA = 0x00fe, ALL = 0x00ff, WINS = 0xff01, WINSR = 0xff02, TLSA = 0x0034, SVCB = 0x0040, HTTPS = 0x0041, pub const NBSTAT: TYPE = .WINSR; pub const ANY: TYPE = .ALL; }; pub const QUERY = packed struct(ULONG64) { pub const STANDARD: QUERY = .{}; ACCEPT_TRUNCATED_RESPONSE: bool = false, USE_TCP_ONLY: bool = false, NO_RECURSION: bool = false, BYPASS_CACHE: bool = false, NO_WIRE_QUERY: bool = false, NO_LOCAL_NAME: bool = false, NO_HOSTS_FILE: bool = false, NO_NETBT: bool = false, WIRE_ONLY: bool = false, RETURN_MESSAGE: bool = false, MULTICAST_ONLY: bool = false, NO_MULTICAST: bool = false, TREAT_AS_FQDN: bool = false, ADDRCONFIG: bool = false, DUAL_ADDR: bool = false, Reserved15: u2 = 0, MULTICAST_WAIT: bool = false, MULTICAST_VERIFY: bool = false, Reserved19: u1 = 0, DONT_RESET_TTL_VALUES: bool = false, DISABLE_IDN_ENCODING: bool = false, Reserved22: u1 = 0, APPEND_MULTILABEL: bool = false, Reserved24: u34 = 0, PARSE_ALL_RECORDS: bool = false, Reserved59: u5 = 0, pub const REQUEST = extern struct { Version: DWORD, QueryName: PCWSTR, QueryType: TYPE, QueryOptions: QUERY = .STANDARD, pDnsServerList: ?*ADDR.ARRAY = null, InterfaceIndex: ULONG = 0, pQueryCompletionCallback: ?*const COMPLETION_ROUTINE = null, pQueryContext: ?*anyopaque = null, pub const @"3" = extern struct { Base: REQUEST, IsNetworkQueryRequired: BOOL = .FALSE, RequiredNetworkIndex: DWORD = 0, cCustomServers: DWORD = 0, pCustomServers: ?*CUSTOM_SERVER = null, }; }; pub const RESULT = extern struct { Version: ULONG, QueryStatus: STATUS, QueryOptions: QUERY, pQueryRecords: ?*RECORD, Reserved: ?*anyopaque, }; pub const CANCEL = extern struct { Reserved: [32]CHAR align(8), }; pub const COMPLETION_ROUTINE = fn ( pQueryContext: ?*anyopaque, pQueryResults: *RESULT, ) callconv(.winapi) void; }; pub const FREE_TYPE = enum(c_int) { Flat = 0, RecordList, ParsedMessageFields }; pub const RECORD = extern struct { pNext: ?*RECORD, pName: *anyopaque, wType: TYPE, wDataLength: WORD, Flags: FLAGS, dwTtl: DWORD, dwReserved: DWORD, Data: extern union { A: [4]u8, AAAA: [16]u8 }, pub const FLAGS = packed struct(DWORD) { Section: SECTION, Delete: u1, CharSet: u2, Unused: u3, Reserved: u24, }; }; pub const SECTION = enum(u2) { Question, Answer, Authority, Additional }; }; // ref: km/ntddk.h pub const SYSTEM = struct { pub const INFORMATION_CLASS = enum(c_int) { Basic = 0, Performance = 2, TimeOfDay = 3, Process = 5, ProcessorPerformance = 8, Interrupt = 23, Exception = 33, RegistryQuota = 37, Lookaside = 45, CodeIntegrity = 103, Policy = 134, _, }; pub const BASIC_INFORMATION = extern struct { Reserved: ULONG, TimerResolution: ULONG, PageSize: ULONG, NumberOfPhysicalPages: ULONG, LowestPhysicalPageNumber: ULONG, HighestPhysicalPageNumber: ULONG, AllocationGranularity: ULONG, MinimumUserModeAddress: ULONG_PTR, MaximumUserModeAddress: ULONG_PTR, ActiveProcessorsAffinityMask: KAFFINITY, NumberOfProcessors: UCHAR, }; }; pub const PROCESS = struct { pub const INFORMATION = extern struct { hProcess: HANDLE, hThread: HANDLE, dwProcessId: DWORD, dwThreadId: DWORD, }; pub const INFOCLASS = enum(c_int) { BasicInformation = 0, QuotaLimits = 1, IoCounters = 2, VmCounters = 3, Times = 4, BasePriority = 5, RaisePriority = 6, DebugPort = 7, ExceptionPort = 8, AccessToken = 9, LdtInformation = 10, LdtSize = 11, DefaultHardErrorMode = 12, IoPortHandlers = 13, PooledUsageAndLimits = 14, WorkingSetWatch = 15, UserModeIOPL = 16, EnableAlignmentFaultFixup = 17, PriorityClass = 18, Wx86Information = 19, HandleCount = 20, AffinityMask = 21, PriorityBoost = 22, DeviceMap = 23, SessionInformation = 24, ForegroundInformation = 25, Wow64Information = 26, ImageFileName = 27, LUIDDeviceMapsEnabled = 28, BreakOnTermination = 29, DebugObjectHandle = 30, DebugFlags = 31, HandleTracing = 32, IoPriority = 33, ExecuteFlags = 34, TlsInformation = 35, Cookie = 36, ImageInformation = 37, CycleTime = 38, PagePriority = 39, InstrumentationCallback = 40, ThreadStackAllocation = 41, WorkingSetWatchEx = 42, ImageFileNameWin32 = 43, ImageFileMapping = 44, AffinityUpdateMode = 45, MemoryAllocationMode = 46, GroupInformation = 47, TokenVirtualizationEnabled = 48, OwnerInformation = 49, WindowInformation = 50, HandleInformation = 51, MitigationPolicy = 52, DynamicFunctionTableInformation = 53, HandleCheckingMode = 54, KeepAliveCount = 55, RevokeFileHandles = 56, WorkingSetControl = 57, HandleTable = 58, CheckStackExtentsMode = 59, CommandLineInformation = 60, ProtectionInformation = 61, MemoryExhaustion = 62, FaultInformation = 63, TelemetryIdInformation = 64, CommitReleaseInformation = 65, Reserved1Information = 66, Reserved2Information = 67, SubsystemProcess = 68, InPrivate = 70, RaiseUMExceptionOnInvalidHandleClose = 71, SubsystemInformation = 75, Win32kSyscallFilterInformation = 79, EnergyTrackingState = 82, NetworkIoCounters = 114, _, pub const Max: @typeInfo(@This()).@"enum".tag_type = 117; }; pub const BASIC_INFORMATION = extern struct { ExitStatus: NTSTATUS, PebBaseAddress: *PEB, AffinityMask: ULONG_PTR, BasePriority: KPRIORITY, UniqueProcessId: ULONG_PTR, InheritedFromUniqueProcessId: ULONG_PTR, }; pub const VM_COUNTERS = extern struct { PeakVirtualSize: SIZE_T, VirtualSize: SIZE_T, PageFaultCount: ULONG, PeakWorkingSetSize: SIZE_T, WorkingSetSize: SIZE_T, QuotaPeakPagedPoolUsage: SIZE_T, QuotaPagedPoolUsage: SIZE_T, QuotaPeakNonPagedPoolUsage: SIZE_T, QuotaNonPagedPoolUsage: SIZE_T, PagefileUsage: SIZE_T, PeakPagefileUsage: SIZE_T, }; }; pub const THREAD = struct { pub const INFOCLASS = enum(c_int) { BasicInformation = 0, Times = 1, Priority = 2, BasePriority = 3, AffinityMask = 4, ImpersonationToken = 5, DescriptorTableEntry = 6, EnableAlignmentFaultFixup = 7, EventPair_Reusable = 8, QuerySetWin32StartAddress = 9, ZeroTlsCell = 10, PerformanceCount = 11, AmILastThread = 12, IdealProcessor = 13, PriorityBoost = 14, SetTlsArrayAddress = 15, IsIoPending = 16, // Windows 2000+ from here HideFromDebugger = 17, // Windows XP+ from here BreakOnTermination = 18, SwitchLegacyState = 19, IsTerminated = 20, // Windows Vista+ from here LastSystemCall = 21, IoPriority = 22, CycleTime = 23, PagePriority = 24, ActualBasePriority = 25, TebInformation = 26, CSwitchMon = 27, // Windows 7+ from here CSwitchPmu = 28, Wow64Context = 29, GroupInformation = 30, UmsInformation = 31, CounterProfiling = 32, IdealProcessorEx = 33, // Windows 8+ from here CpuAccountingInformation = 34, // Windows 8.1+ from here SuspendCount = 35, // Windows 10+ from here HeterogeneousCpuPolicy = 36, ContainerId = 37, NameInformation = 38, SelectedCpuSets = 39, SystemThreadInformation = 40, ActualGroupAffinity = 41, DynamicCodePolicyInfo = 42, SubsystemInformation = 45, _, pub const Max: @typeInfo(@This()).@"enum".tag_type = 60; }; pub const BASIC_INFORMATION = extern struct { ExitStatus: NTSTATUS, TebBaseAddress: PVOID, ClientId: CLIENT_ID, AffinityMask: KAFFINITY, Priority: KPRIORITY, BasePriority: KPRIORITY, }; pub const CREATE_FLAGS = packed struct(ULONG) { CREATE_SUSPENDED: bool = false, SKIP_THREAD_ATTACH: bool = false, HIDE_FROM_DEBUGGER: bool = false, LOADER_WORKER: bool = false, SKIP_LOADER_INIT: bool = false, BYPASS_PROCESS_FREEZE: bool = false, Reserved6: u26 = 0, pub const NONE: CREATE_FLAGS = .{}; }; pub const StackSize = enum(SIZE_T) { /// The default size specified in the executable header default = 0, _, }; }; pub const MEMORY = struct { pub const BASIC_INFORMATION = extern struct { BaseAddress: PVOID, AllocationBase: PVOID, AllocationProtect: DWORD, PartitionId: WORD, RegionSize: SIZE_T, State: DWORD, Protect: DWORD, Type: DWORD, }; }; // ref: km/ntifs.h pub const HEAP = opaque { pub const FLAGS = packed struct(u8) { /// Serialized access is not used when the heap functions access this heap. This option /// applies to all subsequent heap function calls. Alternatively, you can specify this /// option on individual heap function calls. /// /// The low-fragmentation heap (LFH) cannot be enabled for a heap created with this option. /// /// A heap created with this option cannot be locked. NO_SERIALIZE: bool = false, /// Specifies that the heap is growable. Must be specified if `HeapBase` is `NULL`. GROWABLE: bool = false, /// The system raises an exception to indicate failure (for example, an out-of-memory /// condition) for calls to `HeapAlloc` and `HeapReAlloc` instead of returning `NULL`. /// /// To ensure that exceptions are generated for all calls to an allocation function, specify /// `GENERATE_EXCEPTIONS` in the call to `HeapCreate`. In this case, it is not necessary to /// additionally specify `GENERATE_EXCEPTIONS` in the allocation function calls. GENERATE_EXCEPTIONS: bool = false, /// The allocated memory will be initialized to zero. Otherwise, the memory is not /// initialized to zero. ZERO_MEMORY: bool = false, REALLOC_IN_PLACE_ONLY: bool = false, TAIL_CHECKING_ENABLED: bool = false, FREE_CHECKING_ENABLED: bool = false, DISABLE_COALESCE_ON_FREE: bool = false, pub const CLASS = enum(u4) { /// process heap PROCESS, /// private heap PRIVATE, /// Kernel Heap KERNEL, /// GDI heap GDI, /// User heap USER, /// Console heap CONSOLE, /// User Desktop heap USER_DESKTOP, /// Csrss Shared heap CSRSS_SHARED, /// Csr Port heap CSR_PORT, _, pub const MASK: CLASS = @enumFromInt(maxInt(@typeInfo(CLASS).@"enum".tag_type)); }; pub const CREATE = packed struct(ULONG) { COMMON: FLAGS = .{}, SEGMENT_HEAP: bool = false, /// Only applies to segment heap. Applies pointer obfuscation which is /// generally excessive and unnecessary but is necessary for certain insecure /// heaps in win32k. /// /// Specifying HEAP_CREATE_HARDENED prevents the heap from using locks as /// pointers would potentially be exposed in heap metadata lock variables. /// Callers are therefore responsible for synchronizing access to hardened heaps. HARDENED: bool = false, Reserved10: u2 = 0, CLASS: CLASS = @enumFromInt(0), /// Create heap with 16 byte alignment (obsolete) ALIGN_16: bool = false, /// Create heap call tracing enabled (obsolete) ENABLE_TRACING: bool = false, /// Create heap with executable pages /// /// All memory blocks that are allocated from this heap allow code execution, if the /// hardware enforces data execution prevention. Use this flag heap in applications that /// run code from the heap. If `ENABLE_EXECUTE` is not specified and an application /// attempts to run code from a protected page, the application receives an exception /// with the status code `STATUS_ACCESS_VIOLATION`. ENABLE_EXECUTE: bool = false, Reserved19: u13 = 0, pub const VALID_MASK: CREATE = .{ .COMMON = .{ .NO_SERIALIZE = true, .GROWABLE = true, .GENERATE_EXCEPTIONS = true, .ZERO_MEMORY = true, .REALLOC_IN_PLACE_ONLY = true, .TAIL_CHECKING_ENABLED = true, .FREE_CHECKING_ENABLED = true, .DISABLE_COALESCE_ON_FREE = true, }, .CLASS = .MASK, .ALIGN_16 = true, .ENABLE_TRACING = true, .ENABLE_EXECUTE = true, .SEGMENT_HEAP = true, .HARDENED = true, }; }; pub const ALLOCATION = packed struct(ULONG) { COMMON: FLAGS = .{}, SETTABLE_USER: packed struct(u4) { VALUE: u1 = 0, FLAGS: packed struct(u3) { FLAG1: bool = false, FLAG2: bool = false, FLAG3: bool = false, } = .{}, } = .{}, CLASS: CLASS = @enumFromInt(0), Reserved16: u2 = 0, TAG: u12 = 0, Reserved30: u2 = 0, }; }; pub const RTL_PARAMETERS = extern struct { Length: ULONG, SegmentReserve: SIZE_T, SegmentCommit: SIZE_T, DeCommitFreeBlockThreshold: SIZE_T, DeCommitTotalFreeThreshold: SIZE_T, MaximumAllocationSize: SIZE_T, VirtualMemoryThreshold: SIZE_T, InitialCommit: SIZE_T, InitialReserve: SIZE_T, CommitRoutine: *const COMMIT_ROUTINE, Reserved: [2]SIZE_T = @splat(0), pub const COMMIT_ROUTINE = fn ( Base: PVOID, CommitAddress: *PVOID, CommitSize: *SIZE_T, ) callconv(.winapi) NTSTATUS; pub const SEGMENT = extern struct { Version: VERSION, Size: USHORT, Flags: FLG, MemorySource: MEMORY_SOURCE, Reserved: [4]SIZE_T, pub const VERSION = enum(USHORT) { CURRENT = 3, _, }; pub const FLG = packed struct(ULONG) { USE_PAGE_HEAP: bool = false, NO_LFH: bool = false, Reserved2: u30 = 0, pub const VALID_FLAGS: FLG = .{ .USE_PAGE_HEAP = true, .NO_LFH = true, }; }; pub const MEMORY_SOURCE = extern struct { Flags: ULONG, MemoryTypeMask: TYPE, NumaNode: ULONG, u: extern union { PartitionHandle: HANDLE, Callbacks: *const VA_CALLBACKS, }, Reserved: [2]SIZE_T = @splat(0), pub const TYPE = enum(ULONG) { Paged, NonPaged, @"64KPage", LargePage, HugePage, Custom, _, pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".fields.len; }; pub const VA_CALLBACKS = extern struct { CallbackContext: HANDLE, AllocateVirtualMemory: *const ALLOCATE_VIRTUAL_MEMORY_EX_CALLBACK, FreeVirtualMemory: *const FREE_VIRTUAL_MEMORY_EX_CALLBACK, QueryVirtualMemory: *const QUERY_VIRTUAL_MEMORY_CALLBACK, pub const ALLOCATE_VIRTUAL_MEMORY_EX_CALLBACK = fn ( CallbackContext: HANDLE, BaseAddress: *PVOID, RegionSize: *SIZE_T, AllocationType: ULONG, PageProtection: ULONG, ExtendedParameters: ?[*]MEM.EXTENDED_PARAMETER, ExtendedParameterCount: ULONG, ) callconv(.c) NTSTATUS; pub const FREE_VIRTUAL_MEMORY_EX_CALLBACK = fn ( CallbackContext: HANDLE, ProcessHandle: HANDLE, BaseAddress: *PVOID, RegionSize: *SIZE_T, FreeType: ULONG, ) callconv(.c) NTSTATUS; pub const QUERY_VIRTUAL_MEMORY_CALLBACK = fn ( CallbackContext: HANDLE, ProcessHandle: HANDLE, BaseAddress: *PVOID, MemoryInformationClass: MEMORY_INFO_CLASS, MemoryInformation: PVOID, MemoryInformationLength: SIZE_T, ReturnLength: ?*SIZE_T, ) callconv(.c) NTSTATUS; pub const MEMORY_INFO_CLASS = enum(c_int) { Basic, _, }; }; }; }; }; }; pub const CTL_CODE = packed struct(ULONG) { Method: METHOD, Function: u12, Access: FILE_ACCESS, DeviceType: FILE_DEVICE, pub const METHOD = enum(u2) { BUFFERED = 0, IN_DIRECT = 1, OUT_DIRECT = 2, NEITHER = 3, }; pub const FILE_ACCESS = packed struct(u2) { READ: bool = false, WRITE: bool = false, pub const ANY: FILE_ACCESS = .{ .READ = false, .WRITE = false }; pub const SPECIAL = ANY; }; pub const FILE_DEVICE = enum(u16) { BEEP = 0x00000001, CD_ROM = 0x00000002, CD_ROM_FILE_SYSTEM = 0x00000003, CONTROLLER = 0x00000004, DATALINK = 0x00000005, DFS = 0x00000006, DISK = 0x00000007, DISK_FILE_SYSTEM = 0x00000008, FILE_SYSTEM = 0x00000009, INPORT_PORT = 0x0000000a, KEYBOARD = 0x0000000b, MAILSLOT = 0x0000000c, MIDI_IN = 0x0000000d, MIDI_OUT = 0x0000000e, MOUSE = 0x0000000f, MULTI_UNC_PROVIDER = 0x00000010, NAMED_PIPE = 0x00000011, NETWORK = 0x00000012, NETWORK_BROWSER = 0x00000013, NETWORK_FILE_SYSTEM = 0x00000014, NULL = 0x00000015, PARALLEL_PORT = 0x00000016, PHYSICAL_NETCARD = 0x00000017, PRINTER = 0x00000018, SCANNER = 0x00000019, SERIAL_MOUSE_PORT = 0x0000001a, SERIAL_PORT = 0x0000001b, SCREEN = 0x0000001c, SOUND = 0x0000001d, STREAMS = 0x0000001e, TAPE = 0x0000001f, TAPE_FILE_SYSTEM = 0x00000020, TRANSPORT = 0x00000021, UNKNOWN = 0x00000022, VIDEO = 0x00000023, VIRTUAL_DISK = 0x00000024, WAVE_IN = 0x00000025, WAVE_OUT = 0x00000026, @"8042_PORT" = 0x00000027, NETWORK_REDIRECTOR = 0x00000028, BATTERY = 0x00000029, BUS_EXTENDER = 0x0000002a, MODEM = 0x0000002b, VDM = 0x0000002c, MASS_STORAGE = 0x0000002d, SMB = 0x0000002e, KS = 0x0000002f, CHANGER = 0x00000030, SMARTCARD = 0x00000031, ACPI = 0x00000032, DVD = 0x00000033, FULLSCREEN_VIDEO = 0x00000034, DFS_FILE_SYSTEM = 0x00000035, DFS_VOLUME = 0x00000036, SERENUM = 0x00000037, TERMSRV = 0x00000038, KSEC = 0x00000039, FIPS = 0x0000003A, INFINIBAND = 0x0000003B, VMBUS = 0x0000003E, CRYPT_PROVIDER = 0x0000003F, WPD = 0x00000040, BLUETOOTH = 0x00000041, MT_COMPOSITE = 0x00000042, MT_TRANSPORT = 0x00000043, BIOMETRIC = 0x00000044, PMI = 0x00000045, EHSTOR = 0x00000046, DEVAPI = 0x00000047, GPIO = 0x00000048, USBEX = 0x00000049, CONSOLE = 0x00000050, NFP = 0x00000051, SYSENV = 0x00000052, VIRTUAL_BLOCK = 0x00000053, POINT_OF_SERVICE = 0x00000054, STORAGE_REPLICATION = 0x00000055, TRUST_ENV = 0x00000056, UCM = 0x00000057, UCMTCPCI = 0x00000058, PERSISTENT_MEMORY = 0x00000059, NVDIMM = 0x0000005a, HOLOGRAPHIC = 0x0000005b, SDFXHCI = 0x0000005c, UCMUCSI = 0x0000005d, PRM = 0x0000005e, EVENT_COLLECTOR = 0x0000005f, USB4 = 0x00000060, SOUNDWIRE = 0x00000061, MOUNTMGRCONTROLTYPE = 'm', _, }; pub const SET_REPARSE_POINT: CTL_CODE = .{ .DeviceType = .FILE_SYSTEM, .Function = 41, .Method = .BUFFERED, .Access = .SPECIAL }; pub const GET_REPARSE_POINT: CTL_CODE = .{ .DeviceType = .FILE_SYSTEM, .Function = 42, .Method = .BUFFERED, .Access = .ANY }; pub const PIPE = struct { pub const ASSIGN_EVENT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 0, .Method = .BUFFERED, .Access = .ANY }; pub const DISCONNECT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 1, .Method = .BUFFERED, .Access = .ANY }; pub const LISTEN: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2, .Method = .BUFFERED, .Access = .ANY }; pub const PEEK: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 3, .Method = .BUFFERED, .Access = .{ .READ = true } }; pub const QUERY_EVENT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 4, .Method = .BUFFERED, .Access = .ANY }; pub const TRANSCEIVE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 5, .Method = .NEITHER, .Access = .{ .READ = true, .WRITE = true } }; pub const WAIT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 6, .Method = .BUFFERED, .Access = .ANY }; pub const IMPERSONATE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 7, .Method = .BUFFERED, .Access = .ANY }; pub const SET_CLIENT_PROCESS: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 8, .Method = .BUFFERED, .Access = .ANY }; pub const QUERY_CLIENT_PROCESS: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 9, .Method = .BUFFERED, .Access = .ANY }; pub const GET_PIPE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 10, .Method = .BUFFERED, .Access = .ANY }; pub const SET_PIPE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 11, .Method = .BUFFERED, .Access = .ANY }; pub const GET_CONNECTION_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 12, .Method = .BUFFERED, .Access = .ANY }; pub const SET_CONNECTION_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 13, .Method = .BUFFERED, .Access = .ANY }; pub const GET_HANDLE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 14, .Method = .BUFFERED, .Access = .ANY }; pub const SET_HANDLE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 15, .Method = .BUFFERED, .Access = .ANY }; pub const FLUSH: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 16, .Method = .BUFFERED, .Access = .{ .WRITE = true } }; pub const INTERNAL_READ: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2045, .Method = .BUFFERED, .Access = .{ .READ = true } }; pub const INTERNAL_WRITE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2046, .Method = .BUFFERED, .Access = .{ .WRITE = true } }; pub const INTERNAL_TRANSCEIVE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2047, .Method = .NEITHER, .Access = .{ .READ = true, .WRITE = true } }; pub const INTERNAL_READ_OVFLOW: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2048, .Method = .BUFFERED, .Access = .{ .READ = true } }; }; }; pub const IOCTL = struct { pub const AFD = struct { const CONTROL_CODE = packed struct { Method: CTL_CODE.METHOD, Function: u10, DeviceType: CTL_CODE.FILE_DEVICE, Reserved28: u4 = 0, }; pub const BIND: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 0, .Method = .NEITHER }); pub const CONNECT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 1, .Method = .NEITHER }); pub const START_LISTEN: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 2, .Method = .NEITHER }); pub const WAIT_FOR_LISTEN: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 3, .Method = .BUFFERED }); pub const ACCEPT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 4, .Method = .BUFFERED }); pub const RECEIVE: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 5, .Method = .NEITHER }); pub const RECEIVE_DATAGRAM: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 6, .Method = .NEITHER }); pub const SEND: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 7, .Method = .NEITHER }); pub const SEND_DATAGRAM: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 8, .Method = .NEITHER }); pub const POLL: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 9, .Method = .BUFFERED }); pub const PARTIAL_DISCONNECT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 10, .Method = .NEITHER }); pub const GET_ADDRESS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 11, .Method = .NEITHER }); pub const QUERY_RECEIVE_INFO: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 12, .Method = .NEITHER }); pub const QUERY_HANDLES: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 13, .Method = .NEITHER }); pub const SET_INFORMATION: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 14, .Method = .NEITHER }); pub const GET_CONTEXT_LENGTH: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 15, .Method = .NEITHER }); pub const GET_CONTEXT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 16, .Method = .NEITHER }); pub const SET_CONTEXT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 17, .Method = .NEITHER }); pub const SET_CONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 18, .Method = .BUFFERED }); pub const SET_CONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 19, .Method = .BUFFERED }); pub const SET_DISCONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 20, .Method = .BUFFERED }); pub const SET_DISCONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 21, .Method = .BUFFERED }); pub const GET_CONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 22, .Method = .BUFFERED }); pub const GET_CONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 23, .Method = .BUFFERED }); pub const GET_DISCONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 24, .Method = .BUFFERED }); pub const GET_DISCONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 25, .Method = .BUFFERED }); pub const SIZE_CONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 26, .Method = .BUFFERED }); pub const SIZE_CONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 27, .Method = .BUFFERED }); pub const SIZE_DISCONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 28, .Method = .BUFFERED }); pub const SIZE_DISCONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 29, .Method = .BUFFERED }); pub const GET_INFORMATION: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 30, .Method = .NEITHER }); pub const TRANSMIT_FILE: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 31, .Method = .NEITHER }); pub const SUPER_ACCEPT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 32, .Method = .NEITHER }); pub const EVENT_SELECT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 33, .Method = .BUFFERED }); pub const ENUM_NETWORK_EVENTS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 34, .Method = .BUFFERED }); pub const DEFER_ACCEPT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 35, .Method = .BUFFERED }); pub const WAIT_FOR_LISTEN_LIFO: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 36, .Method = .BUFFERED }); pub const SET_QOS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 37, .Method = .BUFFERED }); pub const GET_QOS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 38, .Method = .BUFFERED }); pub const NO_OPERATION: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 39, .Method = .NEITHER }); pub const VALIDATE_GROUP: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 40, .Method = .BUFFERED }); pub const GET_UNACCEPTED_CONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 41, .Method = .BUFFERED }); pub const QUEUE_APC: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 42, .Method = .BUFFERED }); pub const SOCKOPT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 47, .Method = .NEITHER }); pub const SUPER_CONNECT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 49, .Method = .NEITHER }); pub const RECV_MSG: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 51, .Method = .NEITHER }); pub const RIO: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 70, .Method = .NEITHER }); }; pub const CONDRV = struct { pub const READ_IO: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 1, .Method = .OUT_DIRECT, .Access = .ANY }; pub const COMPLETE_IO: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 2, .Method = .NEITHER, .Access = .ANY }; pub const READ_INPUT: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 3, .Method = .NEITHER, .Access = .ANY }; pub const WRITE_OUTPUT: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 4, .Method = .NEITHER, .Access = .ANY }; pub const ISSUE_USER_IO: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 5, .Method = .OUT_DIRECT, .Access = .ANY }; pub const DISCONNECT_PIPE: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 6, .Method = .NEITHER, .Access = .ANY }; pub const SET_SERVER_INFORMATION: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 7, .Method = .NEITHER, .Access = .ANY }; pub const GET_SERVER_PID: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 8, .Method = .NEITHER, .Access = .ANY }; pub const GET_DISPLAY_SIZE: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 9, .Method = .NEITHER, .Access = .ANY }; pub const UPDATE_DISPLAY: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 10, .Method = .NEITHER, .Access = .ANY }; pub const SET_CURSOR: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 11, .Method = .NEITHER, .Access = .ANY }; pub const ALLOW_VIA_UIACCESS: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 12, .Method = .NEITHER, .Access = .ANY }; pub const LAUNCH_SERVER: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 13, .Method = .NEITHER, .Access = .ANY }; pub const GET_FONT_SIZE: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 14, .Method = .NEITHER, .Access = .ANY }; }; pub const KSEC = struct { pub const GEN_RANDOM: CTL_CODE = .{ .DeviceType = .KSEC, .Function = 2, .Method = .BUFFERED, .Access = .ANY }; }; pub const MOUNTMGR = struct { pub const QUERY_POINTS: CTL_CODE = .{ .DeviceType = .MOUNTMGRCONTROLTYPE, .Function = 2, .Method = .BUFFERED, .Access = .ANY }; pub const QUERY_DOS_VOLUME_PATH: CTL_CODE = .{ .DeviceType = .MOUNTMGRCONTROLTYPE, .Function = 12, .Method = .BUFFERED, .Access = .ANY }; }; }; pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: ULONG = 16 * 1024; pub const IO_REPARSE_TAG = packed struct(ULONG) { Value: u12, Index: u4 = 0, ReservedBits: u12 = 0, /// Can have children if a directory. IsDirectory: bool = false, /// Represents another named entity in the system. IsSurrogate: bool = false, /// Must be `false` for non-Microsoft tags. IsReserved: bool = false, /// Owned by Microsoft. IsMicrosoft: bool = false, pub const RESERVED_INVALID: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsReserved = true, .Index = 0x8, .Value = 0x000 }; pub const MOUNT_POINT: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x003 }; pub const HSM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsReserved = true, .Value = 0x004 }; pub const DRIVE_EXTENDER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x005 }; pub const HSM2: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x006 }; pub const SIS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x007 }; pub const WIM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x008 }; pub const CSV: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x009 }; pub const DFS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x00A }; pub const FILTER_MANAGER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x00B }; pub const SYMLINK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x00C }; pub const IIS_CACHE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x010 }; pub const DFSR: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x012 }; pub const DEDUP: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x013 }; pub const APPXSTRM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsReserved = true, .Value = 0x014 }; pub const NFS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x014 }; pub const FILE_PLACEHOLDER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x015 }; pub const DFM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x016 }; pub const WOF: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x017 }; pub inline fn WCI(index: u1) IO_REPARSE_TAG { return .{ .IsMicrosoft = true, .IsDirectory = index == 0x1, .Index = index, .Value = 0x018 }; } pub const GLOBAL_REPARSE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x0019 }; pub inline fn CLOUD(index: u4) IO_REPARSE_TAG { return .{ .IsMicrosoft = true, .IsDirectory = true, .Index = index, .Value = 0x01A }; } pub const APPEXECLINK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x01B }; pub const PROJFS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsDirectory = true, .Value = 0x01C }; pub const LX_SYMLINK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x01D }; pub const STORAGE_SYNC: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x01E }; pub const WCI_TOMBSTONE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x01F }; pub const UNHANDLED: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x020 }; pub const ONEDRIVE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x021 }; pub const PROJFS_TOMBSTONE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x022 }; pub const AF_UNIX: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x023 }; pub const LX_FIFO: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x024 }; pub const LX_CHR: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x025 }; pub const LX_BLK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x026 }; pub const LX_STORAGE_SYNC_FOLDER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsDirectory = true, .Value = 0x027 }; pub inline fn WCI_LINK(index: u1) IO_REPARSE_TAG { return .{ .IsMicrosoft = true, .IsSurrogate = true, .Index = index, .Value = 0x027 }; } pub const DATALESS_CIM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x28 }; }; // ref: km/wdm.h pub const ACCESS_MASK = packed struct(DWORD) { SPECIFIC: Specific = .{ .bits = 0 }, STANDARD: Standard = .{}, Reserved21: u3 = 0, ACCESS_SYSTEM_SECURITY: bool = false, MAXIMUM_ALLOWED: bool = false, Reserved26: u2 = 0, GENERIC: Generic = .{}, pub const Specific = packed union { bits: u16, // ref: km/wdm.h /// Define access rights to files and directories FILE: File, FILE_DIRECTORY: File.Directory, FILE_PIPE: File.Pipe, /// Registry Specific Access Rights. KEY: Key, /// Object Manager Object Type Specific Access Rights. OBJECT_TYPE: ObjectType, /// Object Manager Directory Specific Access Rights. DIRECTORY: Directory, /// Object Manager Symbolic Link Specific Access Rights. SYMBOLIC_LINK: SymbolicLink, /// Section Access Rights. SECTION: Section, /// Session Specific Access Rights. SESSION: Session, /// Process Specific Access Rights. PROCESS: Process, /// Thread Specific Access Rights. THREAD: Thread, /// Partition Specific Access Rights. MEMORY_PARTITION: MemoryPartition, /// Generic mappings for transaction manager rights. TRANSACTIONMANAGER: TransactionManager, /// Generic mappings for transaction rights. TRANSACTION: Transaction, /// Generic mappings for resource manager rights. RESOURCEMANAGER: ResourceManager, /// Generic mappings for enlistment rights. ENLISTMENT: Enlistment, /// Event Specific Access Rights. EVENT: Event, /// Semaphore Specific Access Rights. SEMAPHORE: Semaphore, // ref: km/ntifs.h /// Token Specific Access Rights. TOKEN: Token, // um/winnt.h /// Job Object Specific Access Rights. JOB_OBJECT: JobObject, /// Mutant Specific Access Rights. MUTANT: Mutant, /// Timer Specific Access Rights. TIMER: Timer, /// I/O Completion Specific Access Rights. IO_COMPLETION: IoCompletion, pub const File = packed struct(u16) { READ_DATA: bool = false, WRITE_DATA: bool = false, APPEND_DATA: bool = false, READ_EA: bool = false, WRITE_EA: bool = false, EXECUTE: bool = false, Reserved6: u1 = 0, READ_ATTRIBUTES: bool = false, WRITE_ATTRIBUTES: bool = false, Reserved9: u7 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .FILE = .{ .READ_DATA = true, .WRITE_DATA = true, .APPEND_DATA = true, .READ_EA = true, .WRITE_EA = true, .EXECUTE = true, .Reserved6 = maxInt(@FieldType(File, "Reserved6")), .READ_ATTRIBUTES = true, .WRITE_ATTRIBUTES = true, } }, }; pub const GENERIC_READ: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .READ, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .FILE = .{ .READ_DATA = true, .READ_ATTRIBUTES = true, .READ_EA = true, } }, }; pub const GENERIC_WRITE: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .WRITE, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .FILE = .{ .WRITE_DATA = true, .WRITE_ATTRIBUTES = true, .WRITE_EA = true, .APPEND_DATA = true, } }, }; pub const GENERIC_EXECUTE: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .EXECUTE, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .FILE = .{ .READ_ATTRIBUTES = true, .EXECUTE = true, } }, }; pub const Directory = packed struct(u16) { LIST: bool = false, ADD_FILE: bool = false, ADD_SUBDIRECTORY: bool = false, READ_EA: bool = false, WRITE_EA: bool = false, TRAVERSE: bool = false, DELETE_CHILD: bool = false, READ_ATTRIBUTES: bool = false, WRITE_ATTRIBUTES: bool = false, Reserved9: u7 = 0, }; pub const Pipe = packed struct(u16) { READ_DATA: bool = false, WRITE_DATA: bool = false, CREATE_PIPE_INSTANCE: bool = false, Reserved3: u4 = 0, READ_ATTRIBUTES: bool = false, WRITE_ATTRIBUTES: bool = false, Reserved9: u7 = 0, }; }; pub const Key = packed struct(u16) { /// Required to query the values of a registry key. QUERY_VALUE: bool = false, /// Required to create, delete, or set a registry value. SET_VALUE: bool = false, /// Required to create a subkey of a registry key. CREATE_SUB_KEY: bool = false, /// Required to enumerate the subkeys of a registry key. ENUMERATE_SUB_KEYS: bool = false, /// Required to request change notifications for a registry key or for subkeys of a registry key. NOTIFY: bool = false, /// Reserved for system use. CREATE_LINK: bool = false, Reserved6: u2 = 0, /// Indicates that an application on 64-bit Windows should operate on the 64-bit registry view. /// This flag is ignored by 32-bit Windows. WOW64_64KEY: bool = false, /// Indicates that an application on 64-bit Windows should operate on the 32-bit registry view. /// This flag is ignored by 32-bit Windows. WOW64_32KEY: bool = false, Reserved10: u6 = 0, pub const WOW64_RES: ACCESS_MASK = .{ .SPECIFIC = .{ .KEY = .{ .WOW64_32KEY = true, .WOW64_64KEY = true, } }, }; /// Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values. pub const READ: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .READ, .SYNCHRONIZE = false, }, .SPECIFIC = .{ .KEY = .{ .QUERY_VALUE = true, .ENUMERATE_SUB_KEYS = true, .NOTIFY = true, } }, }; /// Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY access rights. pub const WRITE: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .WRITE, .SYNCHRONIZE = false, }, .SPECIFIC = .{ .KEY = .{ .SET_VALUE = true, .CREATE_SUB_KEY = true, } }, }; /// Equivalent to KEY_READ. pub const EXECUTE = READ; pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .ALL, .SYNCHRONIZE = false, }, .SPECIFIC = .{ .KEY = .{ .QUERY_VALUE = true, .SET_VALUE = true, .CREATE_SUB_KEY = true, .ENUMERATE_SUB_KEYS = true, .NOTIFY = true, .CREATE_LINK = true, } }, }; }; pub const ObjectType = packed struct(u16) { CREATE: bool = false, Reserved1: u15 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED }, .SPECIFIC = .{ .OBJECT_TYPE = .{ .CREATE = true, } }, }; }; pub const Directory = packed struct(u16) { QUERY: bool = false, TRAVERSE: bool = false, CREATE_OBJECT: bool = false, CREATE_SUBDIRECTORY: bool = false, Reserved3: u12 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED }, .SPECIFIC = .{ .DIRECTORY = .{ .QUERY = true, .TRAVERSE = true, .CREATE_OBJECT = true, .CREATE_SUBDIRECTORY = true, } }, }; }; pub const SymbolicLink = packed struct(u16) { QUERY: bool = false, SET: bool = false, Reserved2: u14 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED }, .SPECIFIC = .{ .SYMBOLIC_LINK = .{ .QUERY = true, } }, }; pub const ALL_ACCESS_EX: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED }, .SPECIFIC = .{ .SYMBOLIC_LINK = .{ .QUERY = true, .SET = true, .Reserved2 = maxInt(@FieldType(SymbolicLink, "Reserved2")), } }, }; }; pub const Section = packed struct(u16) { QUERY: bool = false, MAP_WRITE: bool = false, MAP_READ: bool = false, MAP_EXECUTE: bool = false, EXTEND_SIZE: bool = false, /// not included in `ALL_ACCESS` MAP_EXECUTE_EXPLICIT: bool = false, Reserved6: u10 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED }, .SPECIFIC = .{ .SECTION = .{ .QUERY = true, .MAP_WRITE = true, .MAP_READ = true, .MAP_EXECUTE = true, .EXTEND_SIZE = true, } }, }; }; pub const Session = packed struct(u16) { QUERY_ACCESS: bool = false, MODIFY_ACCESS: bool = false, Reserved2: u14 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED }, .SPECIFIC = .{ .SESSION = .{ .QUERY_ACCESS = true, .MODIFY_ACCESS = true, } }, }; }; pub const Process = packed struct(u16) { TERMINATE: bool = false, CREATE_THREAD: bool = false, SET_SESSIONID: bool = false, VM_OPERATION: bool = false, VM_READ: bool = false, VM_WRITE: bool = false, DUP_HANDLE: bool = false, CREATE_PROCESS: bool = false, SET_QUOTA: bool = false, SET_INFORMATION: bool = false, QUERY_INFORMATION: bool = false, SUSPEND_RESUME: bool = false, QUERY_LIMITED_INFORMATION: bool = false, SET_LIMITED_INFORMATION: bool = false, Reserved14: u2 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .PROCESS = .{ .TERMINATE = true, .CREATE_THREAD = true, .SET_SESSIONID = true, .VM_OPERATION = true, .VM_READ = true, .VM_WRITE = true, .DUP_HANDLE = true, .CREATE_PROCESS = true, .SET_QUOTA = true, .SET_INFORMATION = true, .QUERY_INFORMATION = true, .SUSPEND_RESUME = true, .QUERY_LIMITED_INFORMATION = true, .SET_LIMITED_INFORMATION = true, .Reserved14 = maxInt(@FieldType(Process, "Reserved14")), } }, }; }; pub const Thread = packed struct(u16) { TERMINATE: bool = false, SUSPEND_RESUME: bool = false, ALERT: bool = false, GET_CONTEXT: bool = false, SET_CONTEXT: bool = false, SET_INFORMATION: bool = false, QUERY_INFORMATION: bool = false, SET_THREAD_TOKEN: bool = false, IMPERSONATE: bool = false, DIRECT_IMPERSONATION: bool = false, SET_LIMITED_INFORMATION: bool = false, QUERY_LIMITED_INFORMATION: bool = false, RESUME: bool = false, Reserved13: u3 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .THREAD = .{ .TERMINATE = true, .SUSPEND_RESUME = true, .ALERT = true, .GET_CONTEXT = true, .SET_CONTEXT = true, .SET_INFORMATION = true, .QUERY_INFORMATION = true, .SET_THREAD_TOKEN = true, .IMPERSONATE = true, .DIRECT_IMPERSONATION = true, .SET_LIMITED_INFORMATION = true, .QUERY_LIMITED_INFORMATION = true, .RESUME = true, .Reserved13 = maxInt(@FieldType(Thread, "Reserved13")), } }, }; }; pub const MemoryPartition = packed struct(u16) { QUERY_ACCESS: bool = false, MODIFY_ACCESS: bool = false, Required2: u14 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .MEMORY_PARTITION = .{ .QUERY_ACCESS = true, .MODIFY_ACCESS = true, } }, }; }; pub const TransactionManager = packed struct(u16) { QUERY_INFORMATION: bool = false, SET_INFORMATION: bool = false, RECOVER: bool = false, RENAME: bool = false, CREATE_RM: bool = false, /// The following right is intended for DTC's use only; it will be deprecated, and no one else should take a dependency on it. BIND_TRANSACTION: bool = false, Reserved6: u10 = 0, pub const GENERIC_READ: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .READ }, .SPECIFIC = .{ .TRANSACTIONMANAGER = .{ .QUERY_INFORMATION = true, } }, }; pub const GENERIC_WRITE: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .WRITE }, .SPECIFIC = .{ .TRANSACTIONMANAGER = .{ .SET_INFORMATION = true, .RECOVER = true, .RENAME = true, .CREATE_RM = true, } }, }; pub const GENERIC_EXECUTE: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .EXECUTE }, .SPECIFIC = .{ .TRANSACTIONMANAGER = .{} }, }; pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED }, .SPECIFIC = .{ .TRANSACTIONMANAGER = .{ .QUERY_INFORMATION = true, .SET_INFORMATION = true, .RECOVER = true, .RENAME = true, .CREATE_RM = true, .BIND_TRANSACTION = true, } }, }; }; pub const Transaction = packed struct(u16) { QUERY_INFORMATION: bool = false, SET_INFORMATION: bool = false, ENLIST: bool = false, COMMIT: bool = false, ROLLBACK: bool = false, PROPAGATE: bool = false, RIGHT_RESERVED1: bool = false, Reserved7: u9 = 0, pub const GENERIC_READ: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .READ, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .TRANSACTION = .{ .QUERY_INFORMATION = true, } }, }; pub const GENERIC_WRITE: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .WRITE, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .TRANSACTION = .{ .SET_INFORMATION = true, .COMMIT = true, .ENLIST = true, .ROLLBACK = true, .PROPAGATE = true, } }, }; pub const GENERIC_EXECUTE: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .EXECUTE, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .TRANSACTION = .{ .COMMIT = true, .ROLLBACK = true, } }, }; pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .TRANSACTION = .{ .QUERY_INFORMATION = true, .SET_INFORMATION = true, .COMMIT = true, .ENLIST = true, .ROLLBACK = true, .PROPAGATE = true, } }, }; pub const RESOURCE_MANAGER_RIGHTS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .{ .READ_CONTROL = true, }, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .TRANSACTION = .{ .QUERY_INFORMATION = true, .SET_INFORMATION = true, .ENLIST = true, .ROLLBACK = true, .PROPAGATE = true, } }, }; }; pub const ResourceManager = packed struct(u16) { QUERY_INFORMATION: bool = false, SET_INFORMATION: bool = false, RECOVER: bool = false, ENLIST: bool = false, GET_NOTIFICATION: bool = false, REGISTER_PROTOCOL: bool = false, COMPLETE_PROPAGATION: bool = false, Reserved7: u9 = 0, pub const GENERIC_READ: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .READ, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .RESOURCEMANAGER = .{ .QUERY_INFORMATION = true, } }, }; pub const GENERIC_WRITE: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .WRITE, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .RESOURCEMANAGER = .{ .SET_INFORMATION = true, .RECOVER = true, .ENLIST = true, .GET_NOTIFICATION = true, .REGISTER_PROTOCOL = true, .COMPLETE_PROPAGATION = true, } }, }; pub const GENERIC_EXECUTE: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .EXECUTE, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .RESOURCEMANAGER = .{ .RECOVER = true, .ENLIST = true, .GET_NOTIFICATION = true, .COMPLETE_PROPAGATION = true, } }, }; pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .RESOURCEMANAGER = .{ .QUERY_INFORMATION = true, .SET_INFORMATION = true, .RECOVER = true, .ENLIST = true, .GET_NOTIFICATION = true, .REGISTER_PROTOCOL = true, .COMPLETE_PROPAGATION = true, } }, }; }; pub const Enlistment = packed struct(u16) { QUERY_INFORMATION: bool = false, SET_INFORMATION: bool = false, RECOVER: bool = false, SUBORDINATE_RIGHTS: bool = false, SUPERIOR_RIGHTS: bool = false, Reserved5: u11 = 0, pub const GENERIC_READ: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .READ }, .SPECIFIC = .{ .ENLISTMENT = .{ .QUERY_INFORMATION = true, } }, }; pub const GENERIC_WRITE: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .WRITE }, .SPECIFIC = .{ .ENLISTMENT = .{ .SET_INFORMATION = true, .RECOVER = true, .SUBORDINATE_RIGHTS = true, .SUPERIOR_RIGHTS = true, } }, }; pub const GENERIC_EXECUTE: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .EXECUTE }, .SPECIFIC = .{ .ENLISTMENT = .{ .RECOVER = true, .SUBORDINATE_RIGHTS = true, .SUPERIOR_RIGHTS = true, } }, }; pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED }, .SPECIFIC = .{ .ENLISTMENT = .{ .QUERY_INFORMATION = true, .SET_INFORMATION = true, .RECOVER = true, .SUBORDINATE_RIGHTS = true, .SUPERIOR_RIGHTS = true, } }, }; }; pub const Event = packed struct(u16) { QUERY_STATE: bool = false, MODIFY_STATE: bool = false, Reserved2: u14 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .EVENT = .{ .QUERY_STATE = true, .MODIFY_STATE = true, } }, }; }; pub const Semaphore = packed struct(u16) { QUERY_STATE: bool = false, MODIFY_STATE: bool = false, Reserved2: u14 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .SEMAPHORE = .{ .QUERY_STATE = true, .MODIFY_STATE = true, } }, }; }; pub const Token = packed struct(u16) { ASSIGN_PRIMARY: bool = false, DUPLICATE: bool = false, IMPERSONATE: bool = false, QUERY: bool = false, QUERY_SOURCE: bool = false, ADJUST_PRIVILEGES: bool = false, ADJUST_GROUPS: bool = false, ADJUST_DEFAULT: bool = false, ADJUST_SESSIONID: bool = false, Reserved9: u7 = 0, pub const ALL_ACCESS_P: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED }, .SPECIFIC = .{ .TOKEN = .{ .ASSIGN_PRIMARY = true, .DUPLICATE = true, .IMPERSONATE = true, .QUERY = true, .QUERY_SOURCE = true, .ADJUST_PRIVILEGES = true, .ADJUST_GROUPS = true, .ADJUST_DEFAULT = true, } }, }; pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED }, .SPECIFIC = .{ .TOKEN = .{ .ASSIGN_PRIMARY = true, .DUPLICATE = true, .IMPERSONATE = true, .QUERY = true, .QUERY_SOURCE = true, .ADJUST_PRIVILEGES = true, .ADJUST_GROUPS = true, .ADJUST_DEFAULT = true, .ADJUST_SESSIONID = true, } }, }; pub const READ: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .READ }, .SPECIFIC = .{ .TOKEN = .{ .QUERY = true, } }, }; pub const WRITE: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .WRITE }, .SPECIFIC = .{ .TOKEN = .{ .ADJUST_PRIVILEGES = true, .ADJUST_GROUPS = true, .ADJUST_DEFAULT = true, } }, }; pub const EXECUTE: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .EXECUTE }, .SPECIFIC = .{ .TOKEN = .{} }, }; pub const TRUST_CONSTRAINT_MASK: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .READ }, .SPECIFIC = .{ .TOKEN = .{ .QUERY = true, .QUERY_SOURCE = true, } }, }; pub const TRUST_ALLOWED_MASK: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .READ }, .SPECIFIC = .{ .TOKEN = .{ .QUERY = true, .QUERY_SOURCE = true, .DUPLICATE = true, .IMPERSONATE = true, } }, }; }; pub const JobObject = packed struct(u16) { ASSIGN_PROCESS: bool = false, SET_ATTRIBUTES: bool = false, QUERY: bool = false, TERMINATE: bool = false, SET_SECURITY_ATTRIBUTES: bool = false, IMPERSONATE: bool = false, Reserved6: u10 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .JOB_OBJECT = .{ .ASSIGN_PROCESS = true, .SET_ATTRIBUTES = true, .QUERY = true, .TERMINATE = true, .SET_SECURITY_ATTRIBUTES = true, .IMPERSONATE = true, } }, }; }; pub const Mutant = packed struct(u16) { QUERY_STATE: bool = false, Reserved1: u15 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .MUTANT = .{ .QUERY_STATE = true, } }, }; }; pub const Timer = packed struct(u16) { QUERY_STATE: bool = false, MODIFY_STATE: bool = false, Reserved2: u14 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true, }, .SPECIFIC = .{ .TIMER = .{ .QUERY_STATE = true, .MODIFY_STATE = true, } }, }; }; pub const IoCompletion = packed struct(u16) { Reserved0: u1 = 0, MODIFY_STATE: bool = false, Reserved2: u14 = 0, pub const ALL_ACCESS: ACCESS_MASK = .{ .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true }, .SPECIFIC = .{ .IO_COMPLETION = .{ .Reserved0 = maxInt(@FieldType(IoCompletion, "Reserved0")), .MODIFY_STATE = true, } }, }; }; pub const RIGHTS_ALL: Specific = .{ .bits = maxInt(@FieldType(Specific, "bits")) }; }; pub const Standard = packed struct(u5) { RIGHTS: Rights = .{}, SYNCHRONIZE: bool = false, pub const RIGHTS_ALL: Standard = .{ .RIGHTS = .ALL, .SYNCHRONIZE = true, }; pub const Rights = packed struct(u4) { DELETE: bool = false, READ_CONTROL: bool = false, WRITE_DAC: bool = false, WRITE_OWNER: bool = false, pub const REQUIRED: Rights = .{ .DELETE = true, .READ_CONTROL = true, .WRITE_DAC = true, .WRITE_OWNER = true, }; pub const READ: Rights = .{ .READ_CONTROL = true, }; pub const WRITE: Rights = .{ .READ_CONTROL = true, }; pub const EXECUTE: Rights = .{ .READ_CONTROL = true, }; pub const ALL = REQUIRED; }; }; pub const Generic = packed struct(u4) { ALL: bool = false, EXECUTE: bool = false, WRITE: bool = false, READ: bool = false, }; }; pub const DEVICE_TYPE = packed struct(ULONG) { FileDevice: CTL_CODE.FILE_DEVICE, Reserved16: u16 = 0, }; pub const FS_INFORMATION_CLASS = enum(c_int) { Volume = 1, Label = 2, Size = 3, Device = 4, Attribute = 5, Control = 6, FullSize = 7, ObjectId = 8, DriverPath = 9, VolumeFlags = 10, SectorSize = 11, DataCopy = 12, MetadataSize = 13, FullSizeEx = 14, Guid = 15, _, pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".fields.len; }; pub const SECTION_INHERIT = enum(c_int) { Share = 1, Unmap = 2, }; pub const PAGE = packed struct(ULONG) { NOACCESS: bool = false, READONLY: bool = false, READWRITE: bool = false, WRITECOPY: bool = false, EXECUTE: bool = false, EXECUTE_READ: bool = false, EXECUTE_READWRITE: bool = false, EXECUTE_WRITECOPY: bool = false, GUARD: bool = false, NOCACHE: bool = false, WRITECOMBINE: bool = false, GRAPHICS_NOACCESS: bool = false, GRAPHICS_READONLY: bool = false, GRAPHICS_READWRITE: bool = false, GRAPHICS_EXECUTE: bool = false, GRAPHICS_EXECUTE_READ: bool = false, GRAPHICS_EXECUTE_READWRITE: bool = false, GRAPHICS_COHERENT: bool = false, GRAPHICS_NOCACHE: bool = false, Reserved19: u12 = 0, REVERT_TO_FILE_MAP: bool = false, pub fn fromProtection(protection: std.process.MemoryProtection) ?PAGE { // TODO https://github.com/ziglang/zig/issues/22214 return switch (@as(u3, @bitCast(protection))) { 0b000 => .{ .NOACCESS = true }, 0b001 => .{ .READONLY = true }, 0b010 => null, 0b011 => .{ .READWRITE = true }, 0b100 => .{ .EXECUTE = true }, 0b101 => .{ .EXECUTE_READ = true }, 0b110 => null, 0b111 => .{ .EXECUTE_READWRITE = true }, }; } }; pub const MEM = struct { pub const ALLOCATE = packed struct(ULONG) { Reserved0: u12 = 0, COMMIT: bool = false, RESERVE: bool = false, REPLACE_PLACEHOLDER: bool = false, Reserved15: u3 = 0, RESERVE_PLACEHOLDER: bool = false, RESET: bool = false, TOP_DOWN: bool = false, WRITE_WATCH: bool = false, PHYSICAL: bool = false, Reserved23: u1 = 0, RESET_UNDO: bool = false, Reserved25: u4 = 0, LARGE_PAGES: bool = false, Reserved30: u1 = 0, @"4MB_PAGES": bool = false, pub const @"64K_PAGES": ALLOCATE = .{ .LARGE_PAGES = true, .PHYSICAL = true, }; }; pub const FREE = packed struct(ULONG) { COALESCE_PLACEHOLDERS: bool = false, PRESERVE_PLACEHOLDER: bool = false, Reserved2: u12 = 0, DECOMMIT: bool = false, RELEASE: bool = false, FREE: bool = false, Reserved17: u15 = 0, }; pub const MAP = packed struct(ULONG) { Reserved0: u13 = 0, RESERVE: bool = false, REPLACE_PLACEHOLDER: bool = false, Reserved15: u14 = 0, LARGE_PAGES: bool = false, Reserved30: u2 = 0, }; pub const UNMAP = packed struct(ULONG) { WITH_TRANSIENT_BOOST: bool = false, PRESERVE_PLACEHOLDER: bool = false, Reserved2: u30 = 0, }; pub const EXTENDED_PARAMETER = extern struct { s: packed struct(ULONG64) { Type: TYPE, Reserved: u56, }, u: extern union { ULong64: ULONG64, Pointer: PVOID, Size: SIZE_T, Handle: HANDLE, ULong: ULONG, }, pub const TYPE = enum(u8) { InvalidType = 0, AddressRequirements, NumaNode, PartitionHandle, UserPhysicalHandle, AttributeFlags, ImageMachine, _, pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".fields.len; }; }; }; pub const SEC = packed struct(ULONG) { Reserved0: u17 = 0, HUGE_PAGES: bool = false, PARTITION_OWNER_HANDLE: bool = false, @"64K_PAGES": bool = false, Reserved19: u3 = 0, FILE: bool = false, IMAGE: bool = false, PROTECTED_IMAGE: bool = false, RESERVE: bool = false, COMMIT: bool = false, NOCACHE: bool = false, Reserved29: u1 = 0, WRITECOMBINE: bool = false, LARGE_PAGES: bool = false, pub const IMAGE_NO_EXECUTE: SEC = .{ .IMAGE = true, .NOCACHE = true, }; }; pub const ERESOURCE = opaque {}; // ref: shared/ntdef.h pub const EVENT_TYPE = enum(c_int) { Notification, Synchronization, }; pub const TIMER_TYPE = enum(c_int) { Notification, Synchronization, }; pub const WAIT_TYPE = enum(c_int) { All, Any, }; pub const LOGICAL = ULONG; pub const NTSTATUS = @import("windows/ntstatus.zig").NTSTATUS; // ref: um/heapapi.h pub fn GetProcessHeap() ?*HEAP { return peb().ProcessHeap; } // ref none pub fn GetCurrentProcess() HANDLE { const process_pseudo_handle: usize = @bitCast(@as(isize, -1)); return @ptrFromInt(process_pseudo_handle); } pub fn GetCurrentProcessId() DWORD { return @truncate(@intFromPtr(teb().ClientId.UniqueProcess)); } pub fn GetCurrentThread() HANDLE { const thread_pseudo_handle: usize = @bitCast(@as(isize, -2)); return @ptrFromInt(thread_pseudo_handle); } pub fn GetCurrentThreadId() DWORD { return @truncate(@intFromPtr(teb().ClientId.UniqueThread)); } pub fn GetLastError() Win32Error { return teb().LastErrorValue; } pub fn CloseHandle(hObject: HANDLE) void { switch (ntdll.NtClose(hObject)) { .SUCCESS => {}, else => |status| unexpectedStatus(status) catch {}, } } pub const CreateProcessError = error{ FileNotFound, AccessDenied, InvalidName, NameTooLong, InvalidExe, SystemResources, FileBusy, Unexpected, }; pub const CreateProcessFlags = packed struct(u32) { debug_process: bool = false, debug_only_this_process: bool = false, create_suspended: bool = false, detached_process: bool = false, create_new_console: bool = false, normal_priority_class: bool = false, idle_priority_class: bool = false, high_priority_class: bool = false, realtime_priority_class: bool = false, create_new_process_group: bool = false, create_unicode_environment: bool = false, create_separate_wow_vdm: bool = false, create_shared_wow_vdm: bool = false, create_forcedos: bool = false, below_normal_priority_class: bool = false, above_normal_priority_class: bool = false, inherit_parent_affinity: bool = false, inherit_caller_priority: bool = false, create_protected_process: bool = false, extended_startupinfo_present: bool = false, process_mode_background_begin: bool = false, process_mode_background_end: bool = false, create_secure_process: bool = false, _reserved: bool = false, create_breakaway_from_job: bool = false, create_preserve_code_authz_level: bool = false, create_default_error_mode: bool = false, create_no_window: bool = false, profile_user: bool = false, profile_kernel: bool = false, profile_server: bool = false, create_ignore_system_default: bool = false, }; pub fn teb() *TEB { if (builtin.zig_backend == .stage2_c) return @ptrCast(@alignCast(struct { /// This is a workaround for the C backend until zig has the ability to put /// C code in inline assembly. extern fn zig_windows_teb() callconv(.c) *anyopaque; }.zig_windows_teb())); switch (native_arch) { .thumb => return asm ( \\ mrc p15, 0, %[ptr], c13, c0, 2 : [ptr] "=r" (-> *TEB), ), .aarch64 => return asm ( \\ mov %[ptr], x18 : [ptr] "=r" (-> *TEB), ), .x86 => { comptime assert( @offsetOf(TEB, "NtTib") + @offsetOf(@FieldType(TEB, "NtTib"), "Self") == 0x18, ); return asm ( \\ movl %%fs:0x18, %[ptr] : [ptr] "=r" (-> *TEB), ); }, .x86_64 => { comptime assert( @offsetOf(TEB, "NtTib") + @offsetOf(@FieldType(TEB, "NtTib"), "Self") == 0x30, ); return asm ( \\ movq %%gs:0x30, %[ptr] : [ptr] "=r" (-> *TEB), ); }, else => @compileError("unsupported arch"), } } pub fn peb() *PEB { if (builtin.zig_backend == .stage2_c) switch (native_arch) { .x86, .x86_64 => return @ptrCast(@alignCast(struct { /// This is a workaround for the C backend until zig has the ability to put /// C code in inline assembly. extern fn zig_windows_peb() callconv(.c) *anyopaque; }.zig_windows_peb())), else => {}, } else switch (native_arch) { .aarch64 => { comptime assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x60); return asm ( \\ ldr %[ptr], [x18, #0x60] : [ptr] "=r" (-> *PEB), ); }, .x86 => { comptime assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x30); return asm ( \\ movl %%fs:0x30, %[ptr] : [ptr] "=r" (-> *PEB), ); }, .x86_64 => { comptime assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x60); return asm ( \\ movq %%gs:0x60, %[ptr] : [ptr] "=r" (-> *PEB), ); }, else => {}, } return teb().ProcessEnvironmentBlock; } /// A file time is a 64-bit value that represents the number of 100-nanosecond /// intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated /// Universal Time (UTC). /// This function returns the number of nanoseconds since the canonical epoch, /// which is the POSIX one (Jan 01, 1970 AD). pub fn fromSysTime(hns: i64) Io.Timestamp { const adjusted_epoch: i128 = hns + std.time.epoch.windows * (std.time.ns_per_s / 100); return .fromNanoseconds(@intCast(adjusted_epoch * 100)); } pub fn toSysTime(ns: Io.Timestamp) i64 { const hns = @divFloor(ns.nanoseconds, 100); return @as(i64, @intCast(hns)) - std.time.epoch.windows * (std.time.ns_per_s / 100); } /// Use RtlUpcaseUnicodeChar on Windows when not in comptime to avoid including a /// redundant copy of the uppercase data. pub inline fn toUpperWtf16(c: u16) u16 { return (if (builtin.os.tag != .windows or @inComptime()) nls.upcaseW else ntdll.RtlUpcaseUnicodeChar)(c); } /// Compares two WTF16 strings using the equivalent functionality of /// `RtlEqualUnicodeString` (with case insensitive comparison enabled). /// This function can be called on any target. pub fn eqlIgnoreCaseWtf16(a: []const u16, b: []const u16) bool { if (@inComptime() or builtin.os.tag != .windows) { // This function compares the strings code unit by code unit (aka u16-to-u16), // so any length difference implies inequality. In other words, there's no possible // conversion that changes the number of WTF-16 code units needed for the uppercase/lowercase // version in the conversion table since only codepoints <= max(u16) are eligible // for conversion at all. if (a.len != b.len) return false; for (a, b) |a_c, b_c| { // The slices are always WTF-16 LE, so need to convert the elements to native // endianness for the uppercasing const a_c_native = std.mem.littleToNative(u16, a_c); const b_c_native = std.mem.littleToNative(u16, b_c); if (a_c != b_c and toUpperWtf16(a_c_native) != toUpperWtf16(b_c_native)) { return false; } } return true; } // Use RtlEqualUnicodeString on Windows when not in comptime to avoid including a // redundant copy of the uppercase data. return ntdll.RtlEqualUnicodeString(&.init(a), &.init(b), .TRUE).toBool(); } /// Compares two WTF-8 strings using the equivalent functionality of /// `RtlEqualUnicodeString` (with case insensitive comparison enabled). /// This function can be called on any target. /// Assumes `a` and `b` are valid WTF-8. pub fn eqlIgnoreCaseWtf8(a: []const u8, b: []const u8) bool { // A length equality check is not possible here because there are // some codepoints that have a different length uppercase UTF-8 representations // than their lowercase counterparts, e.g. U+0250 (2 bytes) <-> U+2C6F (3 bytes). // There are 7 such codepoints in the uppercase data used by Windows. var a_wtf8_it = std.unicode.Wtf8View.initUnchecked(a).iterator(); var b_wtf8_it = std.unicode.Wtf8View.initUnchecked(b).iterator(); while (true) { const a_cp = a_wtf8_it.nextCodepoint() orelse break; const b_cp = b_wtf8_it.nextCodepoint() orelse return false; if (a_cp <= maxInt(u16) and b_cp <= maxInt(u16)) { if (a_cp != b_cp and toUpperWtf16(@intCast(a_cp)) != toUpperWtf16(@intCast(b_cp))) { return false; } } else if (a_cp != b_cp) { return false; } } // Make sure there are no leftover codepoints in b if (b_wtf8_it.nextCodepoint() != null) return false; return true; } fn testEqlIgnoreCase(comptime expect_eql: bool, comptime a: []const u8, comptime b: []const u8) !void { try std.testing.expectEqual(expect_eql, eqlIgnoreCaseWtf8(a, b)); try std.testing.expectEqual(expect_eql, eqlIgnoreCaseWtf16( std.unicode.utf8ToUtf16LeStringLiteral(a), std.unicode.utf8ToUtf16LeStringLiteral(b), )); try comptime std.testing.expect(expect_eql == eqlIgnoreCaseWtf8(a, b)); try comptime std.testing.expect(expect_eql == eqlIgnoreCaseWtf16( std.unicode.utf8ToUtf16LeStringLiteral(a), std.unicode.utf8ToUtf16LeStringLiteral(b), )); } test "eqlIgnoreCaseWtf16/Wtf8" { try testEqlIgnoreCase(true, "\x01 a B Λ ɐ", "\x01 A b λ Ɐ"); // does not do case-insensitive comparison for codepoints >= U+10000 try testEqlIgnoreCase(false, "𐓏", "𐓷"); } /// The error type for `removeDotDirsSanitized` pub const RemoveDotDirsError = error{TooManyParentDirs}; /// Removes '.' and '..' path components from a "sanitized relative path". /// A "sanitized path" is one where: /// 1) all forward slashes have been replaced with back slashes /// 2) all repeating back slashes have been collapsed /// 3) the path is a relative one (does not start with a back slash) pub fn removeDotDirsSanitized(comptime T: type, path: []T) RemoveDotDirsError!usize { assert(path.len == 0 or path[0] != '\\'); var write_idx: usize = 0; var read_idx: usize = 0; while (read_idx < path.len) { if (path[read_idx] == '.') { if (read_idx + 1 == path.len) return write_idx; const after_dot = path[read_idx + 1]; if (after_dot == '\\') { read_idx += 2; continue; } if (after_dot == '.' and (read_idx + 2 == path.len or path[read_idx + 2] == '\\')) { if (write_idx == 0) return error.TooManyParentDirs; assert(write_idx >= 2); write_idx -= 1; while (true) { write_idx -= 1; if (write_idx == 0) break; if (path[write_idx] == '\\') { write_idx += 1; break; } } if (read_idx + 2 == path.len) return write_idx; read_idx += 3; continue; } } // skip to the next path separator while (true) : (read_idx += 1) { if (read_idx == path.len) return write_idx; path[write_idx] = path[read_idx]; write_idx += 1; if (path[read_idx] == '\\') break; } read_idx += 1; } return write_idx; } /// Normalizes a Windows path with the following steps: /// 1) convert all forward slashes to back slashes /// 2) collapse duplicate back slashes /// 3) remove '.' and '..' directory parts /// Returns the length of the new path. pub fn normalizePath(comptime T: type, path: []T) RemoveDotDirsError!usize { mem.replaceScalar(T, path, '/', '\\'); const new_len = mem.collapseRepeatsLen(T, path, '\\'); const prefix_len: usize = init: { if (new_len >= 1 and path[0] == '\\') break :init 1; if (new_len >= 2 and path[1] == ':') break :init if (new_len >= 3 and path[2] == '\\') @as(usize, 3) else @as(usize, 2); break :init 0; }; return prefix_len + try removeDotDirsSanitized(T, path[prefix_len..new_len]); } /// Returns true if the path starts with `\??\`, which is indicative of an NT path /// but is not enough to fully distinguish between NT paths and Win32 paths, as /// `\??\` is not actually a distinct prefix but rather the path to a special virtual /// folder in the Object Manager. /// /// For example, `\Device\HarddiskVolume2` and `\DosDevices\C:` are also NT paths but /// cannot be distinguished as such by their prefix. /// /// So, inferring whether a path is an NT path or a Win32 path is usually a mistake; /// that information should instead be known ahead-of-time. /// /// If `T` is `u16`, then `path` should be encoded as WTF-16LE. pub fn hasCommonNtPrefix(comptime T: type, path: []const T) bool { // Must be exactly \??\, forward slashes are not allowed const expected_wtf8_prefix = "\\??\\"; const expected_prefix = switch (T) { u8 => expected_wtf8_prefix, u16 => std.unicode.wtf8ToWtf16LeStringLiteral(expected_wtf8_prefix), else => @compileError("unsupported type: " ++ @typeName(T)), }; return mem.startsWith(T, path, expected_prefix); } /// Similar to `RtlNtPathNameToDosPathName` but does not do any heap allocation. /// The possible transformations are: /// \??\C:\Some\Path -> C:\Some\Path /// \??\UNC\server\share\foo -> \\server\share\foo /// If the path does not have the NT namespace prefix, then `error.NotNtPath` is returned. /// /// Functionality is based on the ReactOS test cases found here: /// https://github.com/reactos/reactos/blob/master/modules/rostests/apitests/ntdll/RtlNtPathNameToDosPathName.c /// /// `path` should be encoded as WTF-16LE. /// /// Supports in-place modification (`path` and `out` may refer to the same slice). pub fn ntToWin32Namespace(path: []const u16, out: []u16) error{ NameTooLong, NotNtPath }![]u16 { if (path.len > PATH_MAX_WIDE) return error.NameTooLong; if (!hasCommonNtPrefix(u16, path)) return error.NotNtPath; var dest_index: usize = 0; var after_prefix = path[4..]; // after the `\??\` // The prefix \??\UNC\ means this is a UNC path, in which case the // `\??\UNC\` should be replaced by `\\` (two backslashes) const is_unc = after_prefix.len >= 4 and eqlIgnoreCaseWtf16(after_prefix[0..3], std.unicode.utf8ToUtf16LeStringLiteral("UNC")) and std.fs.path.PathType.windows.isSep(u16, after_prefix[3]); const win32_len = path.len - @as(usize, if (is_unc) 6 else 4); if (out.len < win32_len) return error.NameTooLong; if (is_unc) { out[0] = comptime std.mem.nativeToLittle(u16, '\\'); dest_index += 1; // We want to include the last `\` of `\??\UNC\` after_prefix = path[7..]; } @memmove(out[dest_index..][0..after_prefix.len], after_prefix); return out[0..win32_len]; } test ntToWin32Namespace { const L = std.unicode.utf8ToUtf16LeStringLiteral; var mutable_unc_path_buf = L("\\??\\UNC\\path1\\path2").*; try std.testing.expectEqualSlices(u16, L("\\\\path1\\path2"), try ntToWin32Namespace(&mutable_unc_path_buf, &mutable_unc_path_buf)); var mutable_path_buf = L("\\??\\C:\\test\\").*; try std.testing.expectEqualSlices(u16, L("C:\\test\\"), try ntToWin32Namespace(&mutable_path_buf, &mutable_path_buf)); var too_small_buf: [6]u16 = undefined; try std.testing.expectError(error.NameTooLong, ntToWin32Namespace(L("\\??\\C:\\test"), &too_small_buf)); } inline fn MAKELANGID(p: c_ushort, s: c_ushort) LANGID { return (s << 10) | p; } /// Call this when you made a windows DLL call or something that does SetLastError /// and you get an unexpected error. pub fn unexpectedError(err: Win32Error) UnexpectedError { @branchHint(.cold); if (std.options.unexpected_error_tracing) { std.debug.print("error.Unexpected: GetLastError({d}): {t}\n", .{ err, err }); std.debug.dumpCurrentStackTrace(.{ .first_address = @returnAddress() }); } return error.Unexpected; } /// Call this when you made a windows NtDll call /// and you get an unexpected status. pub fn unexpectedStatus(status: NTSTATUS) UnexpectedError { if (std.options.unexpected_error_tracing) { std.debug.print("error.Unexpected NTSTATUS=0x{x} ({s})\n", .{ @intFromEnum(status), std.enums.tagName(NTSTATUS, status) orelse "", }); std.debug.dumpCurrentStackTrace(.{ .first_address = @returnAddress() }); } return error.Unexpected; } pub fn statusBug(status: NTSTATUS) UnexpectedError { switch (builtin.mode) { .Debug => std.debug.panic("programmer bug caused syscall status: 0x{x} ({s})", .{ @intFromEnum(status), std.enums.tagName(NTSTATUS, status) orelse "", }), else => return error.Unexpected, } } pub fn errorBug(err: Win32Error) UnexpectedError { switch (builtin.mode) { .Debug => std.debug.panic("programmer bug caused syscall error: 0x{x} ({s})", .{ @intFromEnum(err), std.enums.tagName(Win32Error, err) orelse "", }), else => return error.Unexpected, } } pub const Win32Error = @import("windows/win32error.zig").Win32Error; pub const LANG = @import("windows/lang.zig"); pub const SUBLANG = @import("windows/sublang.zig"); pub const BOOL = Bool(c_int); pub const BOOLEAN = Bool(BYTE); pub const BYTE = u8; pub const CHAR = u8; pub const UCHAR = u8; pub const FLOAT = f32; pub const HANDLE = *anyopaque; pub const HCRYPTPROV = ULONG_PTR; pub const ATOM = u16; pub const HBRUSH = *opaque {}; pub const HCURSOR = *opaque {}; pub const HICON = *opaque {}; pub const HINSTANCE = *opaque {}; pub const HMENU = *opaque {}; pub const HMODULE = *opaque {}; pub const HWND = *opaque {}; pub const HDC = *opaque {}; pub const HGLRC = *opaque {}; pub const FARPROC = *opaque {}; pub const PROC = *opaque {}; pub const INT = c_int; pub const LPCSTR = [*:0]const CHAR; pub const LPCVOID = *const anyopaque; pub const LPSTR = [*:0]CHAR; pub const LPVOID = *anyopaque; pub const LPWSTR = [*:0]WCHAR; pub const LPCWSTR = [*:0]const WCHAR; pub const PVOID = *anyopaque; pub const PWSTR = [*:0]WCHAR; pub const PCWSTR = [*:0]const WCHAR; /// Allocated by SysAllocString, freed by SysFreeString pub const BSTR = [*:0]WCHAR; pub const SIZE_T = usize; pub const UINT = c_uint; pub const ULONG_PTR = usize; pub const LONG_PTR = isize; pub const DWORD_PTR = ULONG_PTR; pub const WCHAR = u16; pub const WORD = u16; pub const DWORD = u32; pub const DWORD64 = u64; pub const LARGE_INTEGER = i64; pub const ULARGE_INTEGER = u64; pub const USHORT = u16; pub const SHORT = i16; pub const ULONG = u32; pub const LONG = i32; pub const ULONG64 = u64; pub const ULONGLONG = u64; pub const LONGLONG = i64; pub const LANGID = c_ushort; pub const COLORREF = DWORD; pub const LPARAM = LONG_PTR; pub const va_list = *opaque {}; pub const TCHAR = @compileError("Deprecated: choose between `CHAR` or `WCHAR` directly instead."); pub const LPTSTR = @compileError("Deprecated: choose between `LPSTR` or `LPWSTR` directly instead."); pub const LPCTSTR = @compileError("Deprecated: choose between `LPCSTR` or `LPCWSTR` directly instead."); pub const PTSTR = @compileError("Deprecated: choose between `PSTR` or `PWSTR` directly instead."); pub const PCTSTR = @compileError("Deprecated: choose between `PCSTR` or `PCWSTR` directly instead."); fn STRING(comptime C: type) type { return extern struct { Length: USHORT, MaximumLength: USHORT, Buffer: ?[*]C, pub const empty: @This() = .{ .Length = 0, .MaximumLength = 0, .Buffer = null }; pub fn init(string: []const C) @This() { const len: USHORT = @intCast(@sizeOf(C) * string.len); return .{ .Length = len, .MaximumLength = len, .Buffer = @constCast(string.ptr), }; } pub fn initZ(string: [:0]const C) @This() { const len: USHORT = @intCast(@sizeOf(C) * string.len); return .{ .Length = len, .MaximumLength = len + @sizeOf(C), .Buffer = @constCast(string.ptr), }; } pub fn isEmpty(string: *const @This()) bool { return string.Length == 0; } pub fn slice(string: *const @This()) []C { return if (string.isEmpty()) &.{} else string.Buffer.?[0..@divExact(string.Length, @sizeOf(C))]; } pub fn sliceZ(string: *const @This()) [:0]C { assert(string.Length + @sizeOf(C) <= string.MaximumLength); return string.Buffer.?[0..@divExact(string.Length, @sizeOf(C)) :0]; } }; } pub const ANSI_STRING = STRING(CHAR); pub const UNICODE_STRING = STRING(WCHAR); fn Bool(comptime BackingInteger: type) type { return enum(Backing) { /// false FALSE = 0, /// true _, /// This is not the only truthy value, comparisons against this value are always a bug. pub const TRUE: @This() = @enumFromInt(1); pub const Backing = BackingInteger; pub fn toBool(b: @This()) bool { return b != .FALSE; } pub fn fromBool(b: bool) @This() { return @enumFromInt(@intFromBool(b)); } }; } pub const INVALID_HANDLE_VALUE: HANDLE = @ptrFromInt(maxInt(usize)); pub const INVALID_FILE_ATTRIBUTES: DWORD = maxInt(DWORD); pub const IO_STATUS_BLOCK = extern struct { // "DUMMYUNIONNAME" expands to "u" u: extern union { Status: NTSTATUS, Pointer: ?*anyopaque, }, Information: ULONG_PTR, }; pub const MAX_PATH = 260; pub const SECURITY_ATTRIBUTES = extern struct { nLength: DWORD, lpSecurityDescriptor: ?*anyopaque, bInheritHandle: BOOL, }; pub const STARTUPINFOW = extern struct { cb: DWORD, lpReserved: ?LPWSTR, lpDesktop: ?LPWSTR, lpTitle: ?LPWSTR, dwX: DWORD, dwY: DWORD, dwXSize: DWORD, dwYSize: DWORD, dwXCountChars: DWORD, dwYCountChars: DWORD, dwFillAttribute: DWORD, dwFlags: DWORD, wShowWindow: WORD, cbReserved2: WORD, lpReserved2: ?*BYTE, hStdInput: ?HANDLE, hStdOutput: ?HANDLE, hStdError: ?HANDLE, }; pub const STARTF_FORCEONFEEDBACK = 0x00000040; pub const STARTF_FORCEOFFFEEDBACK = 0x00000080; pub const STARTF_PREVENTPINNING = 0x00002000; pub const STARTF_RUNFULLSCREEN = 0x00000020; pub const STARTF_TITLEISAPPID = 0x00001000; pub const STARTF_TITLEISLINKNAME = 0x00000800; pub const STARTF_UNTRUSTEDSOURCE = 0x00008000; pub const STARTF_USECOUNTCHARS = 0x00000008; pub const STARTF_USEFILLATTRIBUTE = 0x00000010; pub const STARTF_USEHOTKEY = 0x00000200; pub const STARTF_USEPOSITION = 0x00000004; pub const STARTF_USESHOWWINDOW = 0x00000001; pub const STARTF_USESIZE = 0x00000002; pub const STARTF_USESTDHANDLES = 0x00000100; pub const THREAD_START_ROUTINE = fn (LPVOID) callconv(.winapi) DWORD; pub const USER_THREAD_START_ROUTINE = fn (LPVOID) callconv(.winapi) NTSTATUS; pub const FILETIME = extern struct { dwLowDateTime: DWORD, dwHighDateTime: DWORD, }; pub const GUID = extern struct { Data1: u32, Data2: u16, Data3: u16, Data4: [8]u8, const hex_offsets = switch (builtin.target.cpu.arch.endian()) { .big => [16]u6{ 0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34, }, .little => [16]u6{ 6, 4, 2, 0, 11, 9, 16, 14, 19, 21, 24, 26, 28, 30, 32, 34, }, }; pub fn parse(s: []const u8) GUID { assert(s[0] == '{'); assert(s[37] == '}'); return parseNoBraces(s[1 .. s.len - 1]) catch @panic("invalid GUID string"); } pub fn parseNoBraces(s: []const u8) !GUID { assert(s.len == 36); assert(s[8] == '-'); assert(s[13] == '-'); assert(s[18] == '-'); assert(s[23] == '-'); var bytes: [16]u8 = undefined; for (hex_offsets, 0..) |hex_offset, i| { bytes[i] = (try std.fmt.charToDigit(s[hex_offset], 16)) << 4 | try std.fmt.charToDigit(s[hex_offset + 1], 16); } return @as(GUID, @bitCast(bytes)); } pub fn format(self: GUID, w: *std.Io.Writer) std.Io.Writer.Error!void { return w.print("{{{x:0>8}-{x:0>4}-{x:0>4}-{x}-{x}}}", .{ self.Data1, self.Data2, self.Data3, self.Data4[0..2], self.Data4[2..8], }); } }; test GUID { try std.testing.expectEqual( GUID{ .Data1 = 0x01234567, .Data2 = 0x89ab, .Data3 = 0xef10, .Data4 = "\x32\x54\x76\x98\xba\xdc\xfe\x91".*, }, GUID.parse("{01234567-89AB-EF10-3254-7698badcfe91}"), ); try std.testing.expectFmt( "{01234567-89ab-ef10-3254-7698badcfe91}", "{f}", .{GUID.parse("{01234567-89AB-EF10-3254-7698badcfe91}")}, ); try std.testing.expectFmt( "{00000001-0001-0001-0001-000000000001}", "{f}", .{GUID{ .Data1 = 1, .Data2 = 1, .Data3 = 1, .Data4 = [_]u8{ 0, 1, 0, 0, 0, 0, 0, 1 } }}, ); } pub const COORD = extern struct { X: SHORT, Y: SHORT, }; pub const TLS_OUT_OF_INDEXES = 4294967295; pub const IMAGE_TLS_DIRECTORY = extern struct { StartAddressOfRawData: usize, EndAddressOfRawData: usize, AddressOfIndex: usize, AddressOfCallBacks: usize, SizeOfZeroFill: u32, Characteristics: u32, }; pub const IMAGE_TLS_DIRECTORY64 = IMAGE_TLS_DIRECTORY; pub const IMAGE_TLS_DIRECTORY32 = IMAGE_TLS_DIRECTORY; pub const PIMAGE_TLS_CALLBACK = ?*const fn (PVOID, DWORD, PVOID) callconv(.winapi) void; pub const REGSAM = ACCESS_MASK; pub const LSTATUS = LONG; pub const HKEY = *opaque {}; pub const HKEY_CLASSES_ROOT: HKEY = @ptrFromInt(0x80000000); pub const HKEY_CURRENT_USER: HKEY = @ptrFromInt(0x80000001); pub const HKEY_LOCAL_MACHINE: HKEY = @ptrFromInt(0x80000002); pub const HKEY_USERS: HKEY = @ptrFromInt(0x80000003); pub const HKEY_PERFORMANCE_DATA: HKEY = @ptrFromInt(0x80000004); pub const HKEY_PERFORMANCE_TEXT: HKEY = @ptrFromInt(0x80000050); pub const HKEY_PERFORMANCE_NLSTEXT: HKEY = @ptrFromInt(0x80000060); pub const HKEY_CURRENT_CONFIG: HKEY = @ptrFromInt(0x80000005); pub const HKEY_DYN_DATA: HKEY = @ptrFromInt(0x80000006); pub const HKEY_CURRENT_USER_LOCAL_SETTINGS: HKEY = @ptrFromInt(0x80000007); pub const RTL_QUERY_REGISTRY_TABLE = extern struct { QueryRoutine: RTL_QUERY_REGISTRY_ROUTINE, Flags: ULONG, Name: ?PWSTR, EntryContext: ?*anyopaque, DefaultType: REG.ValueType, DefaultData: ?*anyopaque, DefaultLength: ULONG, }; pub const RTL_QUERY_REGISTRY_ROUTINE = ?*const fn ( PWSTR, ULONG, ?*anyopaque, ULONG, ?*anyopaque, ?*anyopaque, ) callconv(.winapi) NTSTATUS; /// Path is a full path pub const RTL_REGISTRY_ABSOLUTE = 0; /// \Registry\Machine\System\CurrentControlSet\Services pub const RTL_REGISTRY_SERVICES = 1; /// \Registry\Machine\System\CurrentControlSet\Control pub const RTL_REGISTRY_CONTROL = 2; /// \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion pub const RTL_REGISTRY_WINDOWS_NT = 3; /// \Registry\Machine\Hardware\DeviceMap pub const RTL_REGISTRY_DEVICEMAP = 4; /// \Registry\User\CurrentUser pub const RTL_REGISTRY_USER = 5; pub const RTL_REGISTRY_MAXIMUM = 6; /// Low order bits are registry handle pub const RTL_REGISTRY_HANDLE = 0x40000000; /// Indicates the key node is optional pub const RTL_REGISTRY_OPTIONAL = 0x80000000; /// Name is a subkey and remainder of table or until next subkey are value /// names for that subkey to look at. pub const RTL_QUERY_REGISTRY_SUBKEY = 0x00000001; /// Reset current key to original key for this and all following table entries. pub const RTL_QUERY_REGISTRY_TOPKEY = 0x00000002; /// Fail if no match found for this table entry. pub const RTL_QUERY_REGISTRY_REQUIRED = 0x00000004; /// Used to mark a table entry that has no value name, just wants a call out, not /// an enumeration of all values. pub const RTL_QUERY_REGISTRY_NOVALUE = 0x00000008; /// Used to suppress the expansion of REG_MULTI_SZ into multiple callouts or /// to prevent the expansion of environment variable values in REG_EXPAND_SZ. pub const RTL_QUERY_REGISTRY_NOEXPAND = 0x00000010; /// QueryRoutine field ignored. EntryContext field points to location to store value. /// For null terminated strings, EntryContext points to UNICODE_STRING structure that /// that describes maximum size of buffer. If .Buffer field is NULL then a buffer is /// allocated. pub const RTL_QUERY_REGISTRY_DIRECT = 0x00000020; /// Used to delete value keys after they are queried. pub const RTL_QUERY_REGISTRY_DELETE = 0x00000040; /// Use this flag with the RTL_QUERY_REGISTRY_DIRECT flag to verify that the REG_XXX type /// of the stored registry value matches the type expected by the caller. /// If the types do not match, the call fails. pub const RTL_QUERY_REGISTRY_TYPECHECK = 0x00000100; /// REG_ is a crowded namespace with a lot of overlapping and unrelated /// defines in the Windows headers, so instead of strictly following the /// Windows headers names, extra namespaces are added here for clarity. pub const REG = struct { pub const ValueType = enum(ULONG) { /// No value type NONE = 0, /// Unicode nul terminated string SZ = 1, /// Unicode nul terminated string (with environment variable references) EXPAND_SZ = 2, /// Free form binary BINARY = 3, /// 32-bit number DWORD = 4, /// 32-bit number DWORD_BIG_ENDIAN = 5, /// Symbolic Link (unicode) LINK = 6, /// Multiple Unicode strings MULTI_SZ = 7, /// Resource list in the resource map RESOURCE_LIST = 8, /// Resource list in the hardware description FULL_RESOURCE_DESCRIPTOR = 9, RESOURCE_REQUIREMENTS_LIST = 10, /// 64-bit number QWORD = 11, _, /// 32-bit number (same as REG_DWORD) pub const DWORD_LITTLE_ENDIAN: ValueType = .DWORD; /// 64-bit number (same as REG_QWORD) pub const QWORD_LITTLE_ENDIAN: ValueType = .QWORD; }; /// Used with NtOpenKeyEx, maybe others pub const OpenOptions = packed struct(ULONG) { Reserved0: u2 = 0, /// Open for backup or restore /// special access rules privilege required BACKUP_RESTORE: bool = false, /// Open symbolic link OPEN_LINK: bool = false, Reserved3: u28 = 0, }; /// Used with NtLoadKeyEx, maybe others pub const LoadOptions = packed struct(ULONG) { /// Restore whole hive volatile WHOLE_HIVE_VOLATILE: bool = false, /// Unwind changes to last flush REFRESH_HIVE: bool = false, /// Never lazy flush this hive NO_LAZY_FLUSH: bool = false, /// Force the restore process even when we have open handles on subkeys FORCE_RESTORE: bool = false, /// Loads the hive visible to the calling process APP_HIVE: bool = false, /// Hive cannot be mounted by any other process while in use PROCESS_PRIVATE: bool = false, /// Starts Hive Journal START_JOURNAL: bool = false, /// Grow hive file in exact 4k increments HIVE_EXACT_FILE_GROWTH: bool = false, /// No RM is started for this hive (no transactions) HIVE_NO_RM: bool = false, /// Legacy single logging is used for this hive HIVE_SINGLE_LOG: bool = false, /// This hive might be used by the OS loader BOOT_HIVE: bool = false, /// Load the hive and return a handle to its root kcb LOAD_HIVE_OPEN_HANDLE: bool = false, /// Flush changes to primary hive file size as part of all flushes FLUSH_HIVE_FILE_GROWTH: bool = false, /// Open a hive's files in read-only mode /// The same flag is used for REG_APP_HIVE_OPEN_READ_ONLY: /// Open an app hive's files in read-only mode (if the hive was not previously loaded). OPEN_READ_ONLY: bool = false, /// Load the hive, but don't allow any modification of it IMMUTABLE: bool = false, /// Do not fall back to impersonating the caller if hive file access fails NO_IMPERSONATION_FALLBACK: bool = false, Reserved16: u16 = 0, }; }; pub const KEY = struct { pub const VALUE = struct { /// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ne-wdm-_key_value_information_class pub const INFORMATION_CLASS = enum(c_int) { Basic = 0, Full = 1, Partial = 2, FullAlign64 = 3, PartialAlign64 = 4, Layer = 5, _, pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".fields.len; }; pub const PARTIAL_INFORMATION = extern struct { TitleIndex: ULONG, Type: REG.ValueType, DataLength: ULONG, Data: [0]UCHAR, pub fn data(info: *const PARTIAL_INFORMATION) []const UCHAR { const ptr: [*]const UCHAR = @ptrCast(&info.Data); return ptr[0..info.DataLength]; } }; }; }; pub const ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4; pub const DISABLE_NEWLINE_AUTO_RETURN = 0x8; pub const FOREGROUND_BLUE = 0x0001; pub const FOREGROUND_GREEN = 0x0002; pub const FOREGROUND_RED = 0x0004; pub const FOREGROUND_INTENSITY = 0x0008; pub const BACKGROUND_BLUE = 0x0010; pub const BACKGROUND_GREEN = 0x0020; pub const BACKGROUND_RED = 0x0040; pub const BACKGROUND_INTENSITY = 0x0080; pub const LIST_ENTRY = extern struct { Flink: *LIST_ENTRY, Blink: *LIST_ENTRY, }; pub const RTL_CRITICAL_SECTION_DEBUG = extern struct { Type: WORD, CreatorBackTraceIndex: WORD, CriticalSection: *RTL_CRITICAL_SECTION, ProcessLocksList: LIST_ENTRY, EntryCount: DWORD, ContentionCount: DWORD, Flags: DWORD, CreatorBackTraceIndexHigh: WORD, SpareWORD: WORD, }; pub const RTL_CRITICAL_SECTION = extern struct { DebugInfo: *RTL_CRITICAL_SECTION_DEBUG, LockCount: LONG, RecursionCount: LONG, OwningThread: HANDLE, LockSemaphore: HANDLE, SpinCount: ULONG_PTR, }; pub const CRITICAL_SECTION = RTL_CRITICAL_SECTION; pub const INIT_ONCE = RTL_RUN_ONCE; pub const INIT_ONCE_STATIC_INIT = RTL_RUN_ONCE_INIT; pub const INIT_ONCE_FN = *const fn (InitOnce: *INIT_ONCE, Parameter: ?*anyopaque, Context: ?*anyopaque) callconv(.winapi) BOOL; pub const RTL_RUN_ONCE = extern struct { Ptr: ?*anyopaque, }; pub const RTL_RUN_ONCE_INIT = RTL_RUN_ONCE{ .Ptr = null }; /// > The maximum path of 32,767 characters is approximate, because the "\\?\" /// > prefix may be expanded to a longer string by the system at run time, and /// > this expansion applies to the total length. /// from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation pub const PATH_MAX_WIDE = 32767; /// > [Each file name component can be] up to the value returned in the /// > lpMaximumComponentLength parameter of the GetVolumeInformation function /// > (this value is commonly 255 characters) /// from https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation /// /// > The value that is stored in the variable that *lpMaximumComponentLength points to is /// > used to indicate that a specified file system supports long names. For example, for /// > a FAT file system that supports long names, the function stores the value 255, rather /// > than the previous 8.3 indicator. Long names can also be supported on systems that use /// > the NTFS file system. /// from https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationw /// /// The assumption being made here is that while lpMaximumComponentLength may vary, it will never /// be larger than 255. /// /// TODO: More verification of this assumption. pub const NAME_MAX = 255; pub const EXCEPTION_DATATYPE_MISALIGNMENT = 0x80000002; pub const EXCEPTION_ACCESS_VIOLATION = 0xc0000005; pub const EXCEPTION_ILLEGAL_INSTRUCTION = 0xc000001d; pub const EXCEPTION_STACK_OVERFLOW = 0xc00000fd; pub const EXCEPTION_CONTINUE_SEARCH = 0; pub const EXCEPTION_RECORD = extern struct { ExceptionCode: u32, ExceptionFlags: u32, ExceptionRecord: *EXCEPTION_RECORD, ExceptionAddress: *anyopaque, NumberParameters: u32, ExceptionInformation: [15]usize, }; pub const FLOATING_SAVE_AREA = switch (native_arch) { .x86 => extern struct { ControlWord: DWORD, StatusWord: DWORD, TagWord: DWORD, ErrorOffset: DWORD, ErrorSelector: DWORD, DataOffset: DWORD, DataSelector: DWORD, RegisterArea: [80]BYTE, Cr0NpxState: DWORD, }, else => @compileError("FLOATING_SAVE_AREA only defined on x86"), }; pub const M128A = switch (native_arch) { .x86_64 => extern struct { Low: ULONGLONG, High: LONGLONG, }, else => @compileError("M128A only defined on x86_64"), }; pub const XMM_SAVE_AREA32 = switch (native_arch) { .x86_64 => extern struct { ControlWord: WORD, StatusWord: WORD, TagWord: BYTE, Reserved1: BYTE, ErrorOpcode: WORD, ErrorOffset: DWORD, ErrorSelector: WORD, Reserved2: WORD, DataOffset: DWORD, DataSelector: WORD, Reserved3: WORD, MxCsr: DWORD, MxCsr_Mask: DWORD, FloatRegisters: [8]M128A, XmmRegisters: [16]M128A, Reserved4: [96]BYTE, }, else => @compileError("XMM_SAVE_AREA32 only defined on x86_64"), }; pub const NEON128 = switch (native_arch) { .thumb => extern struct { Low: ULONGLONG, High: LONGLONG, }, .aarch64 => extern union { DUMMYSTRUCTNAME: extern struct { Low: ULONGLONG, High: LONGLONG, }, D: [2]f64, S: [4]f32, H: [8]WORD, B: [16]BYTE, }, else => @compileError("NEON128 only defined on aarch64"), }; pub const CONTEXT = switch (native_arch) { .x86 => extern struct { ContextFlags: DWORD, Dr0: DWORD, Dr1: DWORD, Dr2: DWORD, Dr3: DWORD, Dr6: DWORD, Dr7: DWORD, FloatSave: FLOATING_SAVE_AREA, SegGs: DWORD, SegFs: DWORD, SegEs: DWORD, SegDs: DWORD, Edi: DWORD, Esi: DWORD, Ebx: DWORD, Edx: DWORD, Ecx: DWORD, Eax: DWORD, Ebp: DWORD, Eip: DWORD, SegCs: DWORD, EFlags: DWORD, Esp: DWORD, SegSs: DWORD, ExtendedRegisters: [512]BYTE, pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize, sp: usize } { return .{ .bp = ctx.Ebp, .ip = ctx.Eip, .sp = ctx.Esp }; } }, .x86_64 => extern struct { P1Home: DWORD64 align(16), P2Home: DWORD64, P3Home: DWORD64, P4Home: DWORD64, P5Home: DWORD64, P6Home: DWORD64, ContextFlags: DWORD, MxCsr: DWORD, SegCs: WORD, SegDs: WORD, SegEs: WORD, SegFs: WORD, SegGs: WORD, SegSs: WORD, EFlags: DWORD, Dr0: DWORD64, Dr1: DWORD64, Dr2: DWORD64, Dr3: DWORD64, Dr6: DWORD64, Dr7: DWORD64, Rax: DWORD64, Rcx: DWORD64, Rdx: DWORD64, Rbx: DWORD64, Rsp: DWORD64, Rbp: DWORD64, Rsi: DWORD64, Rdi: DWORD64, R8: DWORD64, R9: DWORD64, R10: DWORD64, R11: DWORD64, R12: DWORD64, R13: DWORD64, R14: DWORD64, R15: DWORD64, Rip: DWORD64, DUMMYUNIONNAME: extern union { FltSave: XMM_SAVE_AREA32, FloatSave: XMM_SAVE_AREA32, DUMMYSTRUCTNAME: extern struct { Header: [2]M128A, Legacy: [8]M128A, Xmm0: M128A, Xmm1: M128A, Xmm2: M128A, Xmm3: M128A, Xmm4: M128A, Xmm5: M128A, Xmm6: M128A, Xmm7: M128A, Xmm8: M128A, Xmm9: M128A, Xmm10: M128A, Xmm11: M128A, Xmm12: M128A, Xmm13: M128A, Xmm14: M128A, Xmm15: M128A, }, }, VectorRegister: [26]M128A, VectorControl: DWORD64, DebugControl: DWORD64, LastBranchToRip: DWORD64, LastBranchFromRip: DWORD64, LastExceptionToRip: DWORD64, LastExceptionFromRip: DWORD64, pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize, sp: usize } { return .{ .bp = ctx.Rbp, .ip = ctx.Rip, .sp = ctx.Rsp }; } pub fn setIp(ctx: *CONTEXT, ip: usize) void { ctx.Rip = ip; } pub fn setSp(ctx: *CONTEXT, sp: usize) void { ctx.Rsp = sp; } }, .thumb => extern struct { ContextFlags: ULONG, R0: ULONG, R1: ULONG, R2: ULONG, R3: ULONG, R4: ULONG, R5: ULONG, R6: ULONG, R7: ULONG, R8: ULONG, R9: ULONG, R10: ULONG, R11: ULONG, R12: ULONG, Sp: ULONG, Lr: ULONG, Pc: ULONG, Cpsr: ULONG, Fpcsr: ULONG, Padding: ULONG, DUMMYUNIONNAME: extern union { Q: [16]NEON128, D: [32]ULONGLONG, S: [32]ULONG, }, Bvr: [8]ULONG, Bcr: [8]ULONG, Wvr: [1]ULONG, Wcr: [1]ULONG, Padding2: [2]ULONG, pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize, sp: usize } { return .{ .bp = ctx.DUMMYUNIONNAME.S[11], .ip = ctx.Pc, .sp = ctx.Sp, }; } pub fn setIp(ctx: *CONTEXT, ip: usize) void { ctx.Pc = ip; } pub fn setSp(ctx: *CONTEXT, sp: usize) void { ctx.Sp = sp; } }, .aarch64 => extern struct { ContextFlags: ULONG align(16), Cpsr: ULONG, DUMMYUNIONNAME: extern union { DUMMYSTRUCTNAME: extern struct { X0: DWORD64, X1: DWORD64, X2: DWORD64, X3: DWORD64, X4: DWORD64, X5: DWORD64, X6: DWORD64, X7: DWORD64, X8: DWORD64, X9: DWORD64, X10: DWORD64, X11: DWORD64, X12: DWORD64, X13: DWORD64, X14: DWORD64, X15: DWORD64, X16: DWORD64, X17: DWORD64, X18: DWORD64, X19: DWORD64, X20: DWORD64, X21: DWORD64, X22: DWORD64, X23: DWORD64, X24: DWORD64, X25: DWORD64, X26: DWORD64, X27: DWORD64, X28: DWORD64, Fp: DWORD64, Lr: DWORD64, }, X: [31]DWORD64, }, Sp: DWORD64, Pc: DWORD64, V: [32]NEON128, Fpcr: DWORD, Fpsr: DWORD, Bcr: [8]DWORD, Bvr: [8]DWORD64, Wcr: [2]DWORD, Wvr: [2]DWORD64, pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize, sp: usize } { return .{ .bp = ctx.DUMMYUNIONNAME.DUMMYSTRUCTNAME.Fp, .ip = ctx.Pc, .sp = ctx.Sp, }; } pub fn setIp(ctx: *CONTEXT, ip: usize) void { ctx.Pc = ip; } pub fn setSp(ctx: *CONTEXT, sp: usize) void { ctx.Sp = sp; } }, else => @compileError("CONTEXT is not defined for this architecture"), }; pub const RUNTIME_FUNCTION = switch (native_arch) { .x86_64 => extern struct { BeginAddress: DWORD, EndAddress: DWORD, UnwindData: DWORD, }, .thumb => extern struct { BeginAddress: DWORD, DUMMYUNIONNAME: extern union { UnwindData: DWORD, DUMMYSTRUCTNAME: packed struct(u32) { Flag: u2, FunctionLength: u11, Ret: u2, H: u1, Reg: u3, R: u1, L: u1, C: u1, StackAdjust: u10, }, }, }, .aarch64 => extern struct { BeginAddress: DWORD, DUMMYUNIONNAME: extern union { UnwindData: DWORD, DUMMYSTRUCTNAME: packed struct(u32) { Flag: u2, FunctionLength: u11, RegF: u3, RegI: u4, H: u1, CR: u2, FrameSize: u9, }, }, }, else => @compileError("RUNTIME_FUNCTION is not defined for this architecture"), }; pub const KNONVOLATILE_CONTEXT_POINTERS = switch (native_arch) { .x86_64 => extern struct { FloatingContext: [16]?*M128A, IntegerContext: [16]?*ULONG64, }, .thumb => extern struct { R4: ?*DWORD, R5: ?*DWORD, R6: ?*DWORD, R7: ?*DWORD, R8: ?*DWORD, R9: ?*DWORD, R10: ?*DWORD, R11: ?*DWORD, Lr: ?*DWORD, D8: ?*ULONGLONG, D9: ?*ULONGLONG, D10: ?*ULONGLONG, D11: ?*ULONGLONG, D12: ?*ULONGLONG, D13: ?*ULONGLONG, D14: ?*ULONGLONG, D15: ?*ULONGLONG, }, .aarch64 => extern struct { X19: ?*DWORD64, X20: ?*DWORD64, X21: ?*DWORD64, X22: ?*DWORD64, X23: ?*DWORD64, X24: ?*DWORD64, X25: ?*DWORD64, X26: ?*DWORD64, X27: ?*DWORD64, X28: ?*DWORD64, Fp: ?*DWORD64, Lr: ?*DWORD64, D8: ?*DWORD64, D9: ?*DWORD64, D10: ?*DWORD64, D11: ?*DWORD64, D12: ?*DWORD64, D13: ?*DWORD64, D14: ?*DWORD64, D15: ?*DWORD64, }, else => @compileError("KNONVOLATILE_CONTEXT_POINTERS is not defined for this architecture"), }; pub const EXCEPTION_POINTERS = extern struct { ExceptionRecord: *EXCEPTION_RECORD, ContextRecord: *CONTEXT, }; pub const VECTORED_EXCEPTION_HANDLER = *const fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(.winapi) c_long; pub const EXCEPTION_DISPOSITION = i32; pub const EXCEPTION_ROUTINE = *const fn ( ExceptionRecord: ?*EXCEPTION_RECORD, EstablisherFrame: PVOID, ContextRecord: *CONTEXT, DispatcherContext: PVOID, ) callconv(.winapi) EXCEPTION_DISPOSITION; pub const UNWIND_HISTORY_TABLE_SIZE = 12; pub const UNWIND_HISTORY_TABLE_ENTRY = extern struct { ImageBase: ULONG64, FunctionEntry: *RUNTIME_FUNCTION, }; pub const UNWIND_HISTORY_TABLE = extern struct { Count: ULONG, LocalHint: BYTE, GlobalHint: BYTE, Search: BYTE, Once: BYTE, LowAddress: ULONG64, HighAddress: ULONG64, Entry: [UNWIND_HISTORY_TABLE_SIZE]UNWIND_HISTORY_TABLE_ENTRY, }; pub const UNW_FLAG_NHANDLER = 0x0; pub const UNW_FLAG_EHANDLER = 0x1; pub const UNW_FLAG_UHANDLER = 0x2; pub const UNW_FLAG_CHAININFO = 0x4; pub const ACTIVATION_CONTEXT_DATA = opaque {}; pub const ASSEMBLY_STORAGE_MAP = opaque {}; pub const FLS_CALLBACK_INFO = opaque {}; pub const RTL_BITMAP = opaque {}; pub const KAFFINITY = usize; pub const KPRIORITY = i32; pub const CLIENT_ID = extern struct { UniqueProcess: HANDLE, UniqueThread: HANDLE, }; pub const TEB = extern struct { NtTib: NT_TIB, EnvironmentPointer: PVOID, ClientId: CLIENT_ID, ActiveRpcHandle: PVOID, ThreadLocalStoragePointer: PVOID, ProcessEnvironmentBlock: *PEB, LastErrorValue: Win32Error, Reserved2: [399 * @sizeOf(PVOID) - @sizeOf(ULONG)]u8, Reserved3: [1952]u8, TlsSlots: [64]PVOID, Reserved4: [8]u8, Reserved5: [26]PVOID, ReservedForOle: PVOID, Reserved6: [4]PVOID, TlsExpansionSlots: PVOID, }; comptime { // XXX: Without this check we cannot use `std.Io.Writer` on 16-bit platforms. `std.fmt.bufPrint` will hit the unreachable in `PEB.GdiHandleBuffer` without this guard. if (builtin.os.tag == .windows) { // Offsets taken from WinDbg info and Geoff Chappell[1] (RIP) // [1]: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/pebteb/teb/index.htm assert(@offsetOf(TEB, "NtTib") == 0x00); if (@sizeOf(usize) == 4) { assert(@offsetOf(TEB, "EnvironmentPointer") == 0x1C); assert(@offsetOf(TEB, "ClientId") == 0x20); assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x28); assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x2C); assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x30); assert(@offsetOf(TEB, "LastErrorValue") == 0x34); assert(@offsetOf(TEB, "TlsSlots") == 0xe10); } else if (@sizeOf(usize) == 8) { assert(@offsetOf(TEB, "EnvironmentPointer") == 0x38); assert(@offsetOf(TEB, "ClientId") == 0x40); assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x50); assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x58); assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x60); assert(@offsetOf(TEB, "LastErrorValue") == 0x68); assert(@offsetOf(TEB, "TlsSlots") == 0x1480); } } } pub const EXCEPTION_REGISTRATION_RECORD = extern struct { Next: ?*EXCEPTION_REGISTRATION_RECORD, Handler: ?*EXCEPTION_DISPOSITION, }; pub const NT_TIB = extern struct { ExceptionList: ?*EXCEPTION_REGISTRATION_RECORD, StackBase: PVOID, StackLimit: PVOID, SubSystemTib: PVOID, DUMMYUNIONNAME: extern union { FiberData: PVOID, Version: DWORD }, ArbitraryUserPointer: PVOID, Self: ?*@This(), }; /// Process Environment Block /// Microsoft documentation of this is incomplete, the fields here are taken from various resources including: /// - https://github.com/wine-mirror/wine/blob/1aff1e6a370ee8c0213a0fd4b220d121da8527aa/include/winternl.h#L269 /// - https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/index.htm pub const PEB = extern struct { // Versions: All InheritedAddressSpace: BOOLEAN, // Versions: 3.51+ ReadImageFileExecOptions: BOOLEAN, BeingDebugged: BOOLEAN, // Versions: 5.2+ (previously was padding) BitField: UCHAR, // Versions: all Mutant: HANDLE, ImageBaseAddress: HMODULE, Ldr: *PEB_LDR_DATA, ProcessParameters: *RTL_USER_PROCESS_PARAMETERS, SubSystemData: PVOID, ProcessHeap: ?*HEAP, // Versions: 5.1+ FastPebLock: *RTL_CRITICAL_SECTION, // Versions: 5.2+ AtlThunkSListPtr: PVOID, IFEOKey: PVOID, // Versions: 6.0+ /// https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/crossprocessflags.htm CrossProcessFlags: ULONG, // Versions: 6.0+ union1: extern union { KernelCallbackTable: PVOID, UserSharedInfoPtr: PVOID, }, // Versions: 5.1+ SystemReserved: ULONG, // Versions: 5.1, (not 5.2, not 6.0), 6.1+ AtlThunkSListPtr32: ULONG, // Versions: 6.1+ ApiSetMap: PVOID, // Versions: all TlsExpansionCounter: ULONG, // note: there is padding here on 64 bit TlsBitmap: *RTL_BITMAP, TlsBitmapBits: [2]ULONG, /// Our base address of the memory region shared with the CSR server. ReadOnlySharedMemoryBase: PVOID, // Versions: 1703+ SharedData: PVOID, // Versions: all ReadOnlyStaticServerData: *UnknownStaticServerDataIndirection, AnsiCodePageData: PVOID, OemCodePageData: PVOID, UnicodeCaseTableData: PVOID, // Versions: 3.51+ NumberOfProcessors: ULONG, NtGlobalFlag: ULONG, // Versions: all CriticalSectionTimeout: LARGE_INTEGER, // End of Original PEB size // Fields appended in 3.51: HeapSegmentReserve: ULONG_PTR, HeapSegmentCommit: ULONG_PTR, HeapDeCommitTotalFreeThreshold: ULONG_PTR, HeapDeCommitFreeBlockThreshold: ULONG_PTR, NumberOfHeaps: ULONG, MaximumNumberOfHeaps: ULONG, ProcessHeaps: *PVOID, // Fields appended in 4.0: GdiSharedHandleTable: PVOID, ProcessStarterHelper: PVOID, GdiDCAttributeList: ULONG, // note: there is padding here on 64 bit LoaderLock: *RTL_CRITICAL_SECTION, OSMajorVersion: ULONG, OSMinorVersion: ULONG, OSBuildNumber: USHORT, OSCSDVersion: USHORT, OSPlatformId: ULONG, ImageSubSystem: ULONG, ImageSubSystemMajorVersion: ULONG, ImageSubSystemMinorVersion: ULONG, // note: there is padding here on 64 bit ActiveProcessAffinityMask: KAFFINITY, GdiHandleBuffer: [ switch (@sizeOf(usize)) { 4 => 0x22, 8 => 0x3C, else => unreachable, } ]ULONG, // Fields appended in 5.0 (Windows 2000): PostProcessInitRoutine: PVOID, TlsExpansionBitmap: *RTL_BITMAP, TlsExpansionBitmapBits: [32]ULONG, SessionId: ULONG, // note: there is padding here on 64 bit // Versions: 5.1+ AppCompatFlags: ULARGE_INTEGER, AppCompatFlagsUser: ULARGE_INTEGER, ShimData: PVOID, // Versions: 5.0+ AppCompatInfo: PVOID, CSDVersion: UNICODE_STRING, // Fields appended in 5.1 (Windows XP): ActivationContextData: *const ACTIVATION_CONTEXT_DATA, ProcessAssemblyStorageMap: *ASSEMBLY_STORAGE_MAP, SystemDefaultActivationData: *const ACTIVATION_CONTEXT_DATA, SystemAssemblyStorageMap: *ASSEMBLY_STORAGE_MAP, MinimumStackCommit: ULONG_PTR, // Fields appended in 5.2 (Windows Server 2003): FlsCallback: *FLS_CALLBACK_INFO, FlsListHead: LIST_ENTRY, FlsBitmap: *RTL_BITMAP, FlsBitmapBits: [4]ULONG, FlsHighIndex: ULONG, // Fields appended in 6.0 (Windows Vista): WerRegistrationData: PVOID, WerShipAssertPtr: PVOID, // Fields appended in 6.1 (Windows 7): pUnused: PVOID, // previously pContextData pImageHeaderHash: PVOID, /// TODO: https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/tracingflags.htm TracingFlags: ULONG, // Fields appended in 6.2 (Windows 8): /// Base address in the CSRSS address space of the memory region shared with the CSR server. CsrServerReadOnlySharedMemoryBase: ULONGLONG, // Fields appended in 1511: TppWorkerpListLock: ULONG, TppWorkerpList: LIST_ENTRY, WaitOnAddressHashTable: [0x80]PVOID, // Fields appended in 1709: TelemetryCoverageHeader: PVOID, CloudFileFlags: ULONG, /// Details of this structure are unknown, but the existence of the field at offset 8 is known /// from experimentation and from reverse-engineering kernelbase.dll. const UnknownStaticServerDataIndirection = extern struct { unknown: u64, /// In the CSRSS address space. base_static_server_data_addr: u64, }; }; /// The `PEB_LDR_DATA` structure is the main record of what modules are loaded in a process. /// It is essentially the head of three double-linked lists of `LDR.DATA_TABLE_ENTRY` structures which each represent one loaded module. /// /// Microsoft documentation of this is incomplete, the fields here are taken from various resources including: /// - https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb_ldr_data.htm pub const PEB_LDR_DATA = extern struct { // Versions: 3.51 and higher /// The size in bytes of the structure Length: ULONG, /// TRUE if the structure is prepared. Initialized: BOOLEAN, SsHandle: PVOID, InLoadOrderModuleList: LIST_ENTRY, InMemoryOrderModuleList: LIST_ENTRY, InInitializationOrderModuleList: LIST_ENTRY, // Versions: 5.1 and higher /// No known use of this field is known in Windows 8 and higher. EntryInProgress: PVOID, // Versions: 6.0 from Windows Vista SP1, and higher ShutdownInProgress: BOOLEAN, /// Though ShutdownThreadId is declared as a HANDLE, /// it is indeed the thread ID as suggested by its name. /// It is picked up from the UniqueThread member of the CLIENT_ID in the /// TEB of the thread that asks to terminate the process. ShutdownThreadId: HANDLE, }; pub const LDR = struct { /// Microsoft documentation of this is incomplete, the fields here are taken from various resources including: /// - https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb_ldr_data /// - https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntldr/ldr_data_table_entry.htm pub const DATA_TABLE_ENTRY = extern struct { InLoadOrderLinks: LIST_ENTRY, InMemoryOrderLinks: LIST_ENTRY, InInitializationOrderLinks: LIST_ENTRY, DllBase: PVOID, EntryPoint: PVOID, SizeOfImage: ULONG, FullDllName: UNICODE_STRING, BaseDllName: UNICODE_STRING, Reserved5: [3]PVOID, DUMMYUNIONNAME: extern union { CheckSum: ULONG, Reserved6: PVOID, }, TimeDateStamp: ULONG, }; pub const DLL_NOTIFICATION = struct { pub const REASON = enum(ULONG) { LOADED = 1, UNLOADED = 2 }; pub const DATA = extern union { Loaded: LOADED, Unloaded: UNLOADED, pub const LOADED = extern struct { Flags: REGISTER, FullDllName: *const UNICODE_STRING, BaseDllName: *const UNICODE_STRING, DllBase: PVOID, SizeOfImage: ULONG, }; pub const UNLOADED = extern struct { Flags: REGISTER, FullDllName: *const UNICODE_STRING, BaseDllName: *const UNICODE_STRING, DllBase: PVOID, SizeOfImage: ULONG, }; }; pub const COOKIE = *opaque {}; pub const FUNCTION = fn ( NotificationReason: REASON, NotificationData: *const DATA, Context: ?PVOID, ) callconv(.winapi) void; pub const REGISTER = packed struct(ULONG) { Reserved0: u32 = 0, }; }; pub const GET_DLL_HANDLE_EX = packed struct(ULONG) { UNCHANGED_REFCOUNT: bool = false, PIN: bool = false, Reserved2: u30 = 0, }; pub const GET_PROCEDURE_ADDRESS = packed struct(ULONG) { DONT_RECORD_FORWARDER: bool = false, Reserved1: u31 = 0, }; pub const LOAD = packed struct(ULONG) { DONT_RESOLVE_DLL_REFERENCES: bool = false, LIBRARY_AS_DATAFILE: bool = false, PACKAGED_LIBRARY: bool = false, WITH_ALTERED_SEARCH_PATH: bool = false, IGNORE_CODE_AUTHZ_LEVEL: bool = false, LIBRARY_AS_IMAGE_RESOURCE: bool = false, LIBRARY_AS_DATAFILE_EXCLUSIVE: bool = false, LIBRARY_REQUERE_SIGNED_TARGET: bool = false, LIBRARY_SEARCH_DLL_LOAD_DIR: bool = false, LIBRARY_SEARCH_USER_DIRS: bool = false, LIBRARY_SEARCH_SYSTEM32: bool = false, LIBRARY_SEARCH_DEFAULT_DIRS: bool = false, }; }; pub const RTL_USER_PROCESS_PARAMETERS = extern struct { AllocationSize: ULONG, Size: ULONG, Flags: ULONG, DebugFlags: ULONG, ConsoleHandle: HANDLE, ConsoleFlags: ULONG, hStdInput: HANDLE, hStdOutput: HANDLE, hStdError: HANDLE, CurrentDirectory: CURDIR, DllPath: UNICODE_STRING, ImagePathName: UNICODE_STRING, CommandLine: UNICODE_STRING, /// Points to a NUL-terminated sequence of NUL-terminated /// WTF-16 LE encoded `name=value` sequences. /// Example using string literal syntax: /// `"NAME=value\x00foo=bar\x00\x00"` Environment: [*:0]WCHAR, dwX: ULONG, dwY: ULONG, dwXSize: ULONG, dwYSize: ULONG, dwXCountChars: ULONG, dwYCountChars: ULONG, dwFillAttribute: ULONG, dwFlags: ULONG, dwShowWindow: ULONG, WindowTitle: UNICODE_STRING, Desktop: UNICODE_STRING, ShellInfo: UNICODE_STRING, RuntimeInfo: UNICODE_STRING, DLCurrentDirectory: [0x20]RTL_DRIVE_LETTER_CURDIR, }; pub const RTL_DRIVE_LETTER_CURDIR = extern struct { Flags: c_ushort, Length: c_ushort, TimeStamp: ULONG, DosPath: UNICODE_STRING, }; pub const PPS_POST_PROCESS_INIT_ROUTINE = ?*const fn () callconv(.winapi) void; pub const FILE_DIRECTORY_INFORMATION = extern struct { NextEntryOffset: ULONG, FileIndex: ULONG, CreationTime: LARGE_INTEGER, LastAccessTime: LARGE_INTEGER, LastWriteTime: LARGE_INTEGER, ChangeTime: LARGE_INTEGER, EndOfFile: LARGE_INTEGER, AllocationSize: LARGE_INTEGER, FileAttributes: FILE.ATTRIBUTE, FileNameLength: ULONG, FileName: [1]WCHAR, }; pub const FILE_BOTH_DIR_INFORMATION = extern struct { NextEntryOffset: ULONG, FileIndex: ULONG, CreationTime: LARGE_INTEGER, LastAccessTime: LARGE_INTEGER, LastWriteTime: LARGE_INTEGER, ChangeTime: LARGE_INTEGER, EndOfFile: LARGE_INTEGER, AllocationSize: LARGE_INTEGER, FileAttributes: FILE.ATTRIBUTE, FileNameLength: ULONG, EaSize: ULONG, ShortNameLength: CHAR, ShortName: [12]WCHAR, FileName: [1]WCHAR, }; pub const FILE_BOTH_DIRECTORY_INFORMATION = FILE_BOTH_DIR_INFORMATION; /// Helper for iterating a byte buffer of FILE_*_INFORMATION structures (from /// things like NtQueryDirectoryFile calls). pub fn FileInformationIterator(comptime FileInformationType: type) type { return struct { byte_offset: usize = 0, buf: []u8 align(@alignOf(FileInformationType)), pub fn next(self: *@This()) ?*FileInformationType { if (self.byte_offset >= self.buf.len) return null; const cur: *FileInformationType = @ptrCast(@alignCast(&self.buf[self.byte_offset])); if (cur.NextEntryOffset == 0) { self.byte_offset = self.buf.len; } else { self.byte_offset += cur.NextEntryOffset; } return cur; } }; } pub const IO_APC_ROUTINE = fn (?*anyopaque, *IO_STATUS_BLOCK, ULONG) callconv(.winapi) void; pub const CURDIR = extern struct { DosPath: UNICODE_STRING, Handle: HANDLE, }; pub const DUPLICATE_SAME_ACCESS = 2; pub const MODULEINFO = extern struct { lpBaseOfDll: LPVOID, SizeOfImage: DWORD, EntryPoint: LPVOID, }; pub const OSVERSIONINFOW = extern struct { dwOSVersionInfoSize: ULONG, dwMajorVersion: ULONG, dwMinorVersion: ULONG, dwBuildNumber: ULONG, dwPlatformId: ULONG, szCSDVersion: [128]WCHAR, }; pub const RTL_OSVERSIONINFOW = OSVERSIONINFOW; pub const REPARSE_DATA_BUFFER = extern struct { ReparseTag: IO_REPARSE_TAG, ReparseDataLength: USHORT, Reserved: USHORT, DataBuffer: [1]UCHAR, }; pub const SYMBOLIC_LINK_REPARSE_BUFFER = extern struct { SubstituteNameOffset: USHORT, SubstituteNameLength: USHORT, PrintNameOffset: USHORT, PrintNameLength: USHORT, Flags: ULONG, PathBuffer: [1]WCHAR, }; pub const MOUNT_POINT_REPARSE_BUFFER = extern struct { SubstituteNameOffset: USHORT, SubstituteNameLength: USHORT, PrintNameOffset: USHORT, PrintNameLength: USHORT, PathBuffer: [1]WCHAR, }; pub const SYMLINK_FLAG_RELATIVE: ULONG = 0x1; pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1; pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2; pub const MOUNTMGR_MOUNT_POINT = extern struct { SymbolicLinkNameOffset: ULONG, SymbolicLinkNameLength: USHORT, Reserved1: USHORT, UniqueIdOffset: ULONG, UniqueIdLength: USHORT, Reserved2: USHORT, DeviceNameOffset: ULONG, DeviceNameLength: USHORT, Reserved3: USHORT, }; pub const MOUNTMGR_MOUNT_POINTS = extern struct { Size: ULONG, NumberOfMountPoints: ULONG, MountPoints: [1]MOUNTMGR_MOUNT_POINT, }; pub const MOUNTMGR_TARGET_NAME = extern struct { DeviceNameLength: USHORT, DeviceName: [1]WCHAR, }; pub const MOUNTMGR_VOLUME_PATHS = extern struct { MultiSzLength: ULONG, MultiSz: [1]WCHAR, }; pub const SRWLOCK_INIT = SRWLOCK{}; pub const SRWLOCK = extern struct { Ptr: ?PVOID = null, }; pub const CONDITION_VARIABLE_INIT = CONDITION_VARIABLE{}; pub const CONDITION_VARIABLE = extern struct { Ptr: ?PVOID = null, }; /// Processor feature enumeration. pub const PF = enum(DWORD) { /// On a Pentium, a floating-point precision error can occur in rare circumstances. FLOATING_POINT_PRECISION_ERRATA = 0, /// Floating-point operations are emulated using software emulator. /// This function returns a nonzero value if floating-point operations are emulated; otherwise, it returns zero. FLOATING_POINT_EMULATED = 1, /// The atomic compare and exchange operation (cmpxchg) is available. COMPARE_EXCHANGE_DOUBLE = 2, /// The MMX instruction set is available. MMX_INSTRUCTIONS_AVAILABLE = 3, PPC_MOVEMEM_64BIT_OK = 4, ALPHA_BYTE_INSTRUCTIONS = 5, /// The SSE instruction set is available. XMMI_INSTRUCTIONS_AVAILABLE = 6, /// The 3D-Now instruction is available. @"3DNOW_INSTRUCTIONS_AVAILABLE" = 7, /// The RDTSC instruction is available. RDTSC_INSTRUCTION_AVAILABLE = 8, /// The processor is PAE-enabled. PAE_ENABLED = 9, /// The SSE2 instruction set is available. XMMI64_INSTRUCTIONS_AVAILABLE = 10, SSE_DAZ_MODE_AVAILABLE = 11, /// Data execution prevention is enabled. NX_ENABLED = 12, /// The SSE3 instruction set is available. SSE3_INSTRUCTIONS_AVAILABLE = 13, /// The atomic compare and exchange 128-bit operation (cmpxchg16b) is available. COMPARE_EXCHANGE128 = 14, /// The atomic compare 64 and exchange 128-bit operation (cmp8xchg16) is available. COMPARE64_EXCHANGE128 = 15, /// The processor channels are enabled. CHANNELS_ENABLED = 16, /// The processor implements the XSAVI and XRSTOR instructions. XSAVE_ENABLED = 17, /// The VFP/Neon: 32 x 64bit register bank is present. /// This flag has the same meaning as PF_ARM_VFP_EXTENDED_REGISTERS. ARM_VFP_32_REGISTERS_AVAILABLE = 18, /// This ARM processor implements the ARM v8 NEON instruction set. ARM_NEON_INSTRUCTIONS_AVAILABLE = 19, /// Second Level Address Translation is supported by the hardware. SECOND_LEVEL_ADDRESS_TRANSLATION = 20, /// Virtualization is enabled in the firmware and made available by the operating system. VIRT_FIRMWARE_ENABLED = 21, /// RDFSBASE, RDGSBASE, WRFSBASE, and WRGSBASE instructions are available. RDWRFSGBASE_AVAILABLE = 22, /// _fastfail() is available. FASTFAIL_AVAILABLE = 23, /// The divide instruction_available. ARM_DIVIDE_INSTRUCTION_AVAILABLE = 24, /// The 64-bit load/store atomic instructions are available. ARM_64BIT_LOADSTORE_ATOMIC = 25, /// The external cache is available. ARM_EXTERNAL_CACHE_AVAILABLE = 26, /// The floating-point multiply-accumulate instruction is available. ARM_FMAC_INSTRUCTIONS_AVAILABLE = 27, RDRAND_INSTRUCTION_AVAILABLE = 28, /// This ARM processor implements the ARM v8 instructions set. ARM_V8_INSTRUCTIONS_AVAILABLE = 29, /// This ARM processor implements the ARM v8 extra cryptographic instructions (i.e., AES, SHA1 and SHA2). ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE = 30, /// This ARM processor implements the ARM v8 extra CRC32 instructions. ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE = 31, RDTSCP_INSTRUCTION_AVAILABLE = 32, RDPID_INSTRUCTION_AVAILABLE = 33, /// This ARM processor implements the ARM v8.1 atomic instructions (e.g., CAS, SWP). ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE = 34, MONITORX_INSTRUCTION_AVAILABLE = 35, /// The SSSE3 instruction set is available. SSSE3_INSTRUCTIONS_AVAILABLE = 36, /// The SSE4_1 instruction set is available. SSE4_1_INSTRUCTIONS_AVAILABLE = 37, /// The SSE4_2 instruction set is available. SSE4_2_INSTRUCTIONS_AVAILABLE = 38, /// The AVX instruction set is available. AVX_INSTRUCTIONS_AVAILABLE = 39, /// The AVX2 instruction set is available. AVX2_INSTRUCTIONS_AVAILABLE = 40, /// The AVX512F instruction set is available. AVX512F_INSTRUCTIONS_AVAILABLE = 41, ERMS_AVAILABLE = 42, /// This ARM processor implements the ARM v8.2 Dot Product (DP) instructions. ARM_V82_DP_INSTRUCTIONS_AVAILABLE = 43, /// This ARM processor implements the ARM v8.3 JavaScript conversion (JSCVT) instructions. ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE = 44, /// This Arm processor implements the Arm v8.3 LRCPC instructions (for example, LDAPR). Note that certain Arm v8.2 CPUs may optionally support the LRCPC instructions. ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE = 45, /// This Arm processor implements the SVE (Scalable Vector Extension) instructions (FEAT_SVE). ARM_SVE_INSTRUCTIONS_AVAILABLE = 46, /// This Arm processor implements the SVE2 instructions (FEAT_SVE2). ARM_SVE2_INSTRUCTIONS_AVAILABLE = 47, /// This Arm processor implements the SVE2.1 instructions (FEAT_SVE2p1). ARM_SVE2_1_INSTRUCTIONS_AVAILABLE = 48, /// This Arm processor implements the SVE AES instructions (FEAT_SVE_AES). ARM_SVE_AES_INSTRUCTIONS_AVAILABLE = 49, /// This Arm processor implements the SVE 128-bit polynomial multiply long instructions (FEAT_SVE_PMULL128). ARM_SVE_PMULL128_INSTRUCTIONS_AVAILABLE = 50, /// This Arm processor implements the SVE bit permute instructions (FEAT_SVE_BitPerm). ARM_SVE_BITPERM_INSTRUCTIONS_AVAILABLE = 51, /// This Arm processor implements the SVE BF16 (BFloat16) instructions (FEAT_BF16). ARM_SVE_BF16_INSTRUCTIONS_AVAILABLE = 52, /// This Arm processor implements the SVE EBF16 (Extended BFloat16) instructions (FEAT_EBF16). ARM_SVE_EBF16_INSTRUCTIONS_AVAILABLE = 53, /// This Arm processor implements the SVE B16B16 instructions (FEAT_SVE_B16B16). ARM_SVE_B16B16_INSTRUCTIONS_AVAILABLE = 54, /// This Arm processor implements the SVE SHA-3 cryptographic instructions (FEAT_SVE_SHA3). ARM_SVE_SHA3_INSTRUCTIONS_AVAILABLE = 55, /// This Arm processor implements the SVE SM4 cryptographic instructions (FEAT_SVE_SM4). ARM_SVE_SM4_INSTRUCTIONS_AVAILABLE = 56, /// This Arm processor implements the SVE I8MM (Int8 matrix multiply) instructions (FEAT_I8MM). ARM_SVE_I8MM_INSTRUCTIONS_AVAILABLE = 57, /// This Arm processor implements the SVE F32MM (FP32 matrix multiply) instructions (FEAT_F32MM). ARM_SVE_F32MM_INSTRUCTIONS_AVAILABLE = 58, /// This Arm processor implements the SVE F64MM (FP64 matrix multiply) instructions (FEAT_F64MM). ARM_SVE_F64MM_INSTRUCTIONS_AVAILABLE = 59, /// This x64 processor implements the BMI2 instruction set. BMI2_INSTRUCTIONS_AVAILABLE = 60, /// This x64 processor implements the MOVDIR64B instruction. MOVDIR64B_INSTRUCTION_AVAILABLE = 61, /// This Arm processor implements the LSE2 atomic instructions (FEAT_LSE2). ARM_LSE2_AVAILABLE = 62, /// This Arm processor implements the SHA-3 cryptographic instructions (FEAT_SHA3). ARM_SHA3_INSTRUCTIONS_AVAILABLE = 64, /// This Arm processor implements the SHA-512 cryptographic instructions (FEAT_SHA512). ARM_SHA512_INSTRUCTIONS_AVAILABLE = 65, /// This Arm processor implements the I8MM (Int8 matrix multiply) NEON instructions (FEAT_I8MM). ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE = 66, /// This Arm processor implements the FP16 (half-precision floating point) NEON instructions (FEAT_FP16). ARM_V82_FP16_INSTRUCTIONS_AVAILABLE = 67, /// This Arm processor implements the BF16 (BFloat16) NEON instructions (FEAT_BF16). ARM_V86_BF16_INSTRUCTIONS_AVAILABLE = 68, /// This Arm processor implements the EBF16 (Extended BFloat16) NEON instructions (FEAT_EBF16). ARM_V86_EBF16_INSTRUCTIONS_AVAILABLE = 69, /// This Arm processor implements the SME (Scalable Matrix Extension) instructions (FEAT_SME). ARM_SME_INSTRUCTIONS_AVAILABLE = 70, /// This Arm processor implements the SME2 instructions (FEAT_SME2). ARM_SME2_INSTRUCTIONS_AVAILABLE = 71, /// This Arm processor implements the SME2.1 instructions (FEAT_SME2p1). ARM_SME2_1_INSTRUCTIONS_AVAILABLE = 72, /// This Arm processor implements the SME2.2 instructions (FEAT_SME2p2). ARM_SME2_2_INSTRUCTIONS_AVAILABLE = 73, /// This Arm processor implements the SVE AES instructions when in Streaming SVE mode (FEAT_SSVE_AES). ARM_SME_AES_INSTRUCTIONS_AVAILABLE = 74, /// This Arm processor implements the SVE bit permute instructions when in Streaming SVE mode (FEAT_SSVE_BitPerm). ARM_SME_SBITPERM_INSTRUCTIONS_AVAILABLE = 75, /// This Arm processor implements the SVE FMMLA (widening, 4-way, FP8 to FP16) instruction when in Streaming SVE mode (FEAT_SSVE_F8F16MM). ARM_SME_SF8MM4_INSTRUCTIONS_AVAILABLE = 76, /// This Arm processor implements the SVE FMMLA (widening, 8-way, FP8 to FP32) instruction when in Streaming SVE mode (FEAT_SSVE_F8F32MM). ARM_SME_SF8MM8_INSTRUCTIONS_AVAILABLE = 77, /// This Arm processor implements the SVE2 FP8DOT2 instructions when in Streaming SVE mode (FEAT_SSVE_FP8DOT2). ARM_SME_SF8DP2_INSTRUCTIONS_AVAILABLE = 78, /// This Arm processor implements the SVE2 FP8DOT4 instructions when in Streaming SVE mode (FEAT_SSVE_FP8DOT4). ARM_SME_SF8DP4_INSTRUCTIONS_AVAILABLE = 79, /// This Arm processor implements the SVE2 FP8FMA instructions when in Streaming SVE mode (FEAT_SSVE_FP8FMA). ARM_SME_SF8FMA_INSTRUCTIONS_AVAILABLE = 80, /// This Arm processor implements the SME F8F32 instructions (FEAT_SME_F8F32). ARM_SME_F8F32_INSTRUCTIONS_AVAILABLE = 81, /// This Arm processor implements the SME F8F16 instructions (FEAT_SME_F8F16). ARM_SME_F8F16_INSTRUCTIONS_AVAILABLE = 82, /// This Arm processor implements the SME F16F16 instructions (FEAT_SME_F16F16). ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE = 83, /// This Arm processor implements the SME B16B16 instructions (FEAT_SME_B16B16). ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE = 84, /// This Arm processor implements the SME F64F64 instructions (FEAT_SME_F64F64). ARM_SME_F64F64_INSTRUCTIONS_AVAILABLE = 85, /// This Arm processor implements the SME I16I64 instructions (FEAT_SME_I16I64). ARM_SME_I16I64_INSTRUCTIONS_AVAILABLE = 86, /// This Arm processor implements the SME LUTv2 instructions (FEAT_SME_LUTv2). ARM_SME_LUTv2_INSTRUCTIONS_AVAILABLE = 87, /// This Arm processor implements SME FA64 (Full AArch64 instruction set when in Streaming SVE mode) (FEAT_SME_FA64). ARM_SME_FA64_INSTRUCTIONS_AVAILABLE = 88, /// This x64 processor implements the UMONITOR instruction. UMONITOR_INSTRUCTION_AVAILABLE = 89, }; pub const MAX_WOW64_SHARED_ENTRIES = 16; pub const PROCESSOR_FEATURE_MAX = 64; pub const MAXIMUM_XSTATE_FEATURES = 64; pub const KSYSTEM_TIME = extern struct { LowPart: ULONG, High1Time: LONG, High2Time: LONG, }; pub const NT_PRODUCT_TYPE = enum(INT) { NtProductWinNt = 1, NtProductLanManNt, NtProductServer, }; pub const ALTERNATIVE_ARCHITECTURE_TYPE = enum(INT) { StandardDesign, NEC98x86, EndAlternatives, }; pub const XSTATE_FEATURE = extern struct { Offset: ULONG, Size: ULONG, }; pub const XSTATE_CONFIGURATION = extern struct { EnabledFeatures: ULONG64, Size: ULONG, OptimizedSave: ULONG, Features: [MAXIMUM_XSTATE_FEATURES]XSTATE_FEATURE, }; /// Shared Kernel User Data pub const KUSER_SHARED_DATA = extern struct { TickCountLowDeprecated: ULONG, TickCountMultiplier: ULONG, InterruptTime: KSYSTEM_TIME, SystemTime: KSYSTEM_TIME, TimeZoneBias: KSYSTEM_TIME, ImageNumberLow: USHORT, ImageNumberHigh: USHORT, NtSystemRoot: [260]WCHAR, MaxStackTraceDepth: ULONG, CryptoExponent: ULONG, TimeZoneId: ULONG, LargePageMinimum: ULONG, AitSamplingValue: ULONG, AppCompatFlag: ULONG, RNGSeedVersion: ULONGLONG, GlobalValidationRunlevel: ULONG, TimeZoneBiasStamp: LONG, NtBuildNumber: ULONG, NtProductType: NT_PRODUCT_TYPE, ProductTypeIsValid: BOOLEAN, Reserved0: [1]BOOLEAN, NativeProcessorArchitecture: USHORT, NtMajorVersion: ULONG, NtMinorVersion: ULONG, ProcessorFeatures: [PROCESSOR_FEATURE_MAX]BOOLEAN, Reserved1: ULONG, Reserved3: ULONG, TimeSlip: ULONG, AlternativeArchitecture: ALTERNATIVE_ARCHITECTURE_TYPE, BootId: ULONG, SystemExpirationDate: LARGE_INTEGER, SuiteMaskY: ULONG, KdDebuggerEnabled: BOOLEAN, DummyUnion1: extern union { MitigationPolicies: UCHAR, Alt: packed struct(u8) { NXSupportPolicy: u2, SEHValidationPolicy: u2, CurDirDevicesSkippedForDlls: u2, Reserved: u2, }, }, CyclesPerYield: USHORT, ActiveConsoleId: ULONG, DismountCount: ULONG, ComPlusPackage: ULONG, LastSystemRITEventTickCount: ULONG, NumberOfPhysicalPages: ULONG, SafeBootMode: BOOLEAN, DummyUnion2: extern union { VirtualizationFlags: UCHAR, Alt: packed struct(u8) { ArchStartedInEl2: u1, QcSlIsSupported: u1, SpareBits: u6, }, }, Reserved12: [2]UCHAR, DummyUnion3: extern union { SharedDataFlags: ULONG, Alt: packed struct(u32) { DbgErrorPortPresent: u1, DbgElevationEnabled: u1, DbgVirtEnabled: u1, DbgInstallerDetectEnabled: u1, DbgLkgEnabled: u1, DbgDynProcessorEnabled: u1, DbgConsoleBrokerEnabled: u1, DbgSecureBootEnabled: u1, DbgMultiSessionSku: u1, DbgMultiUsersInSessionSku: u1, DbgStateSeparationEnabled: u1, SpareBits: u21, }, }, DataFlagsPad: [1]ULONG, TestRetInstruction: ULONGLONG, QpcFrequency: LONGLONG, SystemCall: ULONG, Reserved2: ULONG, SystemCallPad: [2]ULONGLONG, DummyUnion4: extern union { TickCount: KSYSTEM_TIME, TickCountQuad: ULONG64, Alt: extern struct { ReservedTickCountOverlay: [3]ULONG, TickCountPad: [1]ULONG, }, }, Cookie: ULONG, CookiePad: [1]ULONG, ConsoleSessionForegroundProcessId: LONGLONG, TimeUpdateLock: ULONGLONG, BaselineSystemTimeQpc: ULONGLONG, BaselineInterruptTimeQpc: ULONGLONG, QpcSystemTimeIncrement: ULONGLONG, QpcInterruptTimeIncrement: ULONGLONG, QpcSystemTimeIncrementShift: UCHAR, QpcInterruptTimeIncrementShift: UCHAR, UnparkedProcessorCount: USHORT, EnclaveFeatureMask: [4]ULONG, TelemetryCoverageRound: ULONG, UserModeGlobalLogger: [16]USHORT, ImageFileExecutionOptions: ULONG, LangGenerationCount: ULONG, Reserved4: ULONGLONG, InterruptTimeBias: ULONGLONG, QpcBias: ULONGLONG, ActiveProcessorCount: ULONG, ActiveGroupCount: UCHAR, Reserved9: UCHAR, DummyUnion5: extern union { QpcData: USHORT, Alt: extern struct { QpcBypassEnabled: UCHAR, QpcShift: UCHAR, }, }, TimeZoneBiasEffectiveStart: LARGE_INTEGER, TimeZoneBiasEffectiveEnd: LARGE_INTEGER, XState: XSTATE_CONFIGURATION, FeatureConfigurationChangeStamp: KSYSTEM_TIME, Spare: ULONG, UserPointerAuthMask: ULONG64, }; /// Read-only user-mode address for the shared data. /// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntexapi_x/kuser_shared_data/index.htm /// https://msrc-blog.microsoft.com/2022/04/05/randomizing-the-kuser_shared_data-structure-on-windows/ pub const SharedUserData: *const KUSER_SHARED_DATA = @ptrFromInt(0x7FFE0000); pub fn IsProcessorFeaturePresent(feature: PF) bool { if (@intFromEnum(feature) >= PROCESSOR_FEATURE_MAX) return false; return SharedUserData.ProcessorFeatures[@intFromEnum(feature)].toBool(); } // https://github.com/reactos/reactos/blob/master/sdk/include/ndk/pstypes.h#L977-L983 pub const KERNEL_USER_TIMES = extern struct { CreationTime: LARGE_INTEGER, ExitTime: LARGE_INTEGER, KernelTime: LARGE_INTEGER, UserTime: LARGE_INTEGER, }; pub fn wtf8ToWtf16Le(wtf16le: []u16, wtf8: []const u8) error{ BadPathName, NameTooLong }!usize { // Each u8 in UTF-8/WTF-8 correlates to at most one u16 in UTF-16LE/WTF-16LE. if (wtf16le.len < wtf8.len) { const utf16_len = std.unicode.calcUtf16LeLenImpl(wtf8, .can_encode_surrogate_half) catch return error.BadPathName; if (utf16_len > wtf16le.len) return error.NameTooLong; } return std.unicode.wtf8ToWtf16Le(wtf16le, wtf8) catch |err| switch (err) { error.InvalidWtf8 => return error.BadPathName, }; } /// Returns the path to the system directory, typically "C:\\WINDOWS\\System32". /// /// Equivalent to `GetSystemDirectoryW` in kernel32. pub fn getSystemDirectoryWtf16Le() [:0]const u16 { const ssd: *const BASE_STATIC_SERVER_DATA = @ptrCast(@alignCast(relocateCsrssAddress( peb().ReadOnlyStaticServerData.base_static_server_data_addr, ))); return ssd.windows_system_directory.relocate().sliceZ(); } // https://github.com/reactos/reactos/blob/4b75ec5508d47b726d1210e24f5a849dae4e3bda/sdk/include/reactos/subsys/win/base.h#L119 const BASE_STATIC_SERVER_DATA = extern struct { windows_directory: ForeignString, windows_system_directory: ForeignString, named_object_directory: ForeignString, /// This matches the 64-bit version of `UNICODE_STRING`---even on 32-bit targets, this string is /// from 64-bit code (since it comes from CSRSS which is running outside of WOW64). const ForeignString = extern struct { length: u16, maximum_length: u16, /// Address in the CSRSS address space. To convert this to a valid pointer in *our* address /// space, see `relocateCsrssAddress` (or the `ForeignString.relocate` wrapper function). buffer_address: u64, fn relocate(str: ForeignString) UNICODE_STRING { return .{ .Length = str.length, .MaximumLength = str.maximum_length, .Buffer = @ptrCast(@alignCast(@constCast(relocateCsrssAddress(str.buffer_address)))), }; } }; }; /// Takes an address in the CSRSS address space's mapped view of the shared memory region, and /// returns the corresponding address in *our* mapped view of the shared memory region. fn relocateCsrssAddress(addr: u64) *const anyopaque { const base: [*]const u8 = @ptrCast(peb().ReadOnlySharedMemoryBase); const offset: usize = @intCast(addr - peb().CsrServerReadOnlySharedMemoryBase); return base + offset; }