1//! This file contains thin wrappers around Windows-specific APIs, with these
2//! specific goals in mind:
3//! * Convert "errno"-style error codes into Zig errors.
4//! * When null-terminated or WTF16LE byte buffers are required, provide APIs which accept
5//! slices as well as APIs which accept null-terminated WTF16LE byte buffers.
6
7const builtin = @import("builtin");
8const native_arch = builtin.cpu.arch;
9
10const std = @import("../std.zig");
11const Io = std.Io;
12const mem = std.mem;
13const assert = std.debug.assert;
14const math = std.math;
15const maxInt = std.math.maxInt;
16const UnexpectedError = std.posix.UnexpectedError;
17
18pub const kernel32 = @import("windows/kernel32.zig");
19pub const ntdll = @import("windows/ntdll.zig");
20pub const ws2_32 = @import("windows/ws2_32.zig");
21pub const crypt32 = @import("windows/crypt32.zig");
22pub const nls = @import("windows/nls.zig");
23
24pub const current_process: HANDLE = @ptrFromInt(@as(usize, @bitCast(@as(isize, -1))));
25
26pub const PS = struct {
27 pub const ATTRIBUTE = extern struct {
28 Attribute: Type,
29 Size: SIZE_T,
30 u: extern union {
31 Value: ULONG_PTR,
32 ValuePtr: PVOID,
33 },
34 ReturnLength: ?*SIZE_T,
35
36 /// https://ntdoc.m417z.com/ps_attribute_num
37 /// Tag type is `u16` based on PS_ATTRIBUTE_NUMBER_MASK being 0xFFFF
38 pub const NUM = enum(u16) {
39 ParentProcess = 0,
40 DebugObject,
41 Token,
42 ClientId,
43 TebAddress,
44 ImageName,
45 ImageInfo,
46 MemoryReserve,
47 PriorityClass,
48 ErrorMode,
49 StdHandleInfo,
50 HandleList,
51 GroupAffinity,
52 PreferredNode,
53 IdealProcessor,
54 UmsThread,
55 MitigationOptions,
56 ProtectionLevel,
57 SecureProcess,
58 JobList,
59 ChildProcessPolicy,
60 AllApplicationPackagesPolicy,
61 Win32kFilter,
62 SafeOpenPromptOriginClaim,
63 BnoIsolation,
64 DesktopAppPolicy,
65 Chpe,
66 MitigationAuditOptions,
67 MachineType,
68 ComponentFilter,
69 EnableOptionalXStateFeatures,
70 SupportedMachines,
71 SveVectorLength,
72 };
73
74 /// https://ntdoc.m417z.com/psattributevalue
75 pub const Type = enum(ULONG_PTR) {
76 TEB_ADDRESS = construct(.TebAddress, true, false, false),
77 _,
78
79 pub fn construct(num: NUM, thread: bool, input: bool, additive: bool) ULONG_PTR {
80 var val: ULONG_PTR = @backingInt(num);
81 if (thread) val |= 0x10000;
82 if (input) val |= 0x20000;
83 if (additive) val |= 0x40000;
84 return val;
85 }
86 };
87
88 pub const LIST = extern struct {
89 TotalLength: SIZE_T,
90 Attributes: [1]ATTRIBUTE,
91 };
92 };
93};
94
95pub const OBJECT = struct {
96 // ref: um/winternl.h
97
98 pub const ATTRIBUTES = extern struct {
99 Length: ULONG = @sizeOf(ATTRIBUTES),
100 RootDirectory: ?HANDLE = null,
101 ObjectName: ?*UNICODE_STRING = @constCast(&UNICODE_STRING.empty),
102 Attributes: Flags = .{},
103 SecurityDescriptor: ?*anyopaque = null,
104 SecurityQualityOfService: ?*anyopaque = null,
105
106 // Valid values for the Attributes field
107 pub const Flags = packed struct(ULONG) {
108 Reserved0: u1 = 0,
109 INHERIT: bool = false,
110 Reserved2: u2 = 0,
111 PERMANENT: bool = false,
112 EXCLUSIVE: bool = false,
113 /// If name-lookup code should ignore the case of the ObjectName member rather than performing an exact-match search.
114 CASE_INSENSITIVE: bool = true,
115 OPENIF: bool = false,
116 OPENLINK: bool = false,
117 KERNEL_HANDLE: bool = false,
118 FORCE_ACCESS_CHECK: bool = false,
119 IGNORE_IMPERSONATED_DEVICEMAP: bool = false,
120 DONT_REPARSE: bool = false,
121 Reserved13: u19 = 0,
122
123 pub const VALID_ATTRIBUTES: ATTRIBUTES = .{
124 .INHERIT = true,
125 .PERMANENT = true,
126 .EXCLUSIVE = true,
127 .CASE_INSENSITIVE = true,
128 .OPENIF = true,
129 .OPENLINK = true,
130 .KERNEL_HANDLE = true,
131 .FORCE_ACCESS_CHECK = true,
132 .IGNORE_IMPERSONATED_DEVICEMAP = true,
133 .DONT_REPARSE = true,
134 };
135 };
136 };
137
138 pub const INFORMATION_CLASS = enum(c_int) {
139 Basic = 0,
140 Name = 1,
141 Type = 2,
142 Types = 3,
143 HandleFlag = 4,
144 Session = 5,
145 _,
146
147 pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".field_names.len;
148 };
149
150 pub const NAME_INFORMATION = extern struct {
151 Name: UNICODE_STRING,
152 };
153};
154
155pub const FILE = struct {
156 // ref: km/ntddk.h
157
158 pub const END_OF_FILE_INFORMATION = extern struct {
159 EndOfFile: LARGE_INTEGER,
160 };
161
162 pub const ALIGNMENT_INFORMATION = extern struct {
163 AlignmentRequirement: ULONG,
164 };
165
166 pub const NAME_INFORMATION = extern struct {
167 FileNameLength: ULONG,
168 FileName: [1]WCHAR,
169 };
170
171 pub const DISPOSITION = packed struct(ULONG) {
172 DELETE: bool = false,
173 POSIX_SEMANTICS: bool = false,
174 FORCE_IMAGE_SECTION_CHECK: bool = false,
175 ON_CLOSE: bool = false,
176 IGNORE_READONLY_ATTRIBUTE: bool = false,
177 Reserved5: u27 = 0,
178
179 pub const DO_NOT_DELETE: DISPOSITION = .{};
180
181 pub const INFORMATION = extern struct {
182 DeleteFile: BOOLEAN,
183
184 pub const EX = extern struct {
185 Flags: DISPOSITION,
186 };
187 };
188 };
189
190 pub const FS_VOLUME_INFORMATION = extern struct {
191 VolumeCreationTime: LARGE_INTEGER,
192 VolumeSerialNumber: ULONG,
193 VolumeLabelLength: ULONG,
194 SupportsObjects: BOOLEAN,
195 VolumeLabel: [0]WCHAR,
196
197 pub fn getVolumeLabel(fvi: *const FS_VOLUME_INFORMATION) []const WCHAR {
198 return (&fvi).ptr[0..@divExact(fvi.VolumeLabelLength, @sizeOf(WCHAR))];
199 }
200 };
201
202 // ref: km/ntifs.h
203
204 pub const NAME_FLAGS = packed struct(UCHAR) {
205 NTFS: bool = false,
206 DOS: bool = false,
207 Reserved2: u5 = 0,
208 UNSPECIFIED: bool = false,
209 };
210
211 pub const NOTIFY = struct {
212 pub const CHANGE = packed struct(ULONG) {
213 FILE_NAME: bool = false,
214 DIR_NAME: bool = false,
215 ATTRIBUTES: bool = false,
216 SIZE: bool = false,
217 LAST_WRITE: bool = false,
218 LAST_ACCESS: bool = false,
219 CREATION: bool = false,
220 EA: bool = false,
221 SECURITY: bool = false,
222 STREAM_NAME: bool = false,
223 STREAM_SIZE: bool = false,
224 STREAM_WRITE: bool = false,
225 Reserved12: u20 = 0,
226 };
227
228 pub const INFORMATION = extern struct {
229 NextEntryOffset: ULONG,
230 Action: ULONG,
231 FileNameLength: ULONG,
232 FileName: [0]WCHAR,
233
234 pub fn fileName(info: *INFORMATION) []WCHAR {
235 const ptr: [*]WCHAR = @ptrCast(&info.FileName);
236 return ptr[0..@divExact(info.FileNameLength, @sizeOf(WCHAR))];
237 }
238 };
239
240 pub const EXTENDED_INFORMATION = extern struct {
241 NextEntryOffset: ULONG,
242 Action: ULONG,
243 CreationTime: LARGE_INTEGER,
244 LastModificationTime: LARGE_INTEGER,
245 LastChangeTime: LARGE_INTEGER,
246 LastAccessTime: LARGE_INTEGER,
247 AllocatedLength: LARGE_INTEGER,
248 FileSize: LARGE_INTEGER,
249 FileAttributes: ATTRIBUTE,
250 u: extern union {
251 ReparsePointTag: ULONG,
252 EaSize: ULONG,
253 },
254 FileId: LARGE_INTEGER,
255 ParentFileId: LARGE_INTEGER,
256 FileNameLength: ULONG,
257 FileName: [0]WCHAR,
258
259 pub fn fileName(info: *INFORMATION) []WCHAR {
260 const ptr: [*]WCHAR = @ptrCast(&info.FileName);
261 return ptr[0..@divExact(info.FileNameLength, @sizeOf(WCHAR))];
262 }
263 };
264
265 pub const FULL_INFORMATION = extern struct {
266 NextEntryOffset: ULONG,
267 Action: ULONG,
268 CreationTime: LARGE_INTEGER,
269 LastModificationTime: LARGE_INTEGER,
270 LastChangeTime: LARGE_INTEGER,
271 LastAccessTime: LARGE_INTEGER,
272 AllocatedLength: LARGE_INTEGER,
273 FileSize: LARGE_INTEGER,
274 FileAttributes: ATTRIBUTE,
275 u: extern union {
276 ReparsePointTag: ULONG,
277 EaSize: ULONG,
278 },
279 FileId: LARGE_INTEGER,
280 ParentFileId: LARGE_INTEGER,
281 FileNameLength: ULONG,
282 FileNameFlags: NAME_FLAGS,
283 FileName: [0]WCHAR,
284
285 pub fn fileName(info: *INFORMATION) []WCHAR {
286 const ptr: [*]WCHAR = @ptrCast(&info.FileName);
287 return ptr[0..@divExact(info.FileNameLength, @sizeOf(WCHAR))];
288 }
289 };
290 };
291
292 pub const PIPE = struct {
293 /// Define the `NamedPipeType` flags for `NtCreateNamedPipeFile`
294 pub const TYPE = packed struct(ULONG) {
295 TYPE: enum(u1) {
296 BYTE_STREAM = 0b0,
297 MESSAGE = 0b1,
298 } = .BYTE_STREAM,
299 REMOTE_CLIENTS: enum(u1) {
300 ACCEPT = 0b0,
301 REJECT = 0b1,
302 } = .ACCEPT,
303 Reserved2: u30 = 0,
304
305 pub const VALID_MASK: TYPE = .{
306 .TYPE = .MESSAGE,
307 .REMOTE_CLIENTS = .REJECT,
308 };
309 };
310
311 /// Define the `CompletionMode` flags for `NtCreateNamedPipeFile`
312 pub const COMPLETION_MODE = packed struct(ULONG) {
313 OPERATION: enum(u1) {
314 QUEUE = 0b0,
315 COMPLETE = 0b1,
316 } = .QUEUE,
317 Reserved1: u31 = 0,
318 };
319
320 /// Define the `ReadMode` flags for `NtCreateNamedPipeFile`
321 pub const READ_MODE = packed struct(ULONG) {
322 MODE: enum(u1) {
323 BYTE_STREAM = 0b0,
324 MESSAGE = 0b1,
325 },
326 Reserved1: u31 = 0,
327 };
328
329 /// Define the `NamedPipeConfiguration` flags for `NtQueryInformationFile`
330 pub const CONFIGURATION = enum(ULONG) {
331 INBOUND = 0x00000000,
332 OUTBOUND = 0x00000001,
333 FULL_DUPLEX = 0x00000002,
334 };
335
336 /// Define the `NamedPipeState` flags for `NtQueryInformationFile`
337 pub const STATE = enum(ULONG) {
338 DISCONNECTED = 0x00000001,
339 LISTENING = 0x00000002,
340 CONNECTED = 0x00000003,
341 CLOSING = 0x00000004,
342 };
343
344 /// Define the `NamedPipeEnd` flags for `NtQueryInformationFile`
345 pub const END = enum(ULONG) {
346 CLIENT = 0x00000000,
347 SERVER = 0x00000001,
348 };
349
350 pub const INFORMATION = extern struct {
351 ReadMode: READ_MODE,
352 CompletionMode: COMPLETION_MODE,
353 };
354
355 pub const LOCAL_INFORMATION = extern struct {
356 NamedPipeType: TYPE,
357 NamedPipeConfiguration: CONFIGURATION,
358 MaximumInstances: ULONG,
359 CurrentInstances: ULONG,
360 InboundQuota: ULONG,
361 ReadDataAvailable: ULONG,
362 OutboundQuota: ULONG,
363 WriteQuotaAvailable: ULONG,
364 NamedPipeState: STATE,
365 NamedPipeEnd: END,
366 };
367
368 pub const REMOTE_INFORMATION = extern struct {
369 CollectDataTime: LARGE_INTEGER,
370 MaximumCollectionCount: ULONG,
371 };
372
373 pub const WAIT_FOR_BUFFER = extern struct {
374 Timeout: LARGE_INTEGER,
375 NameLength: ULONG,
376 TimeoutSpecified: BOOLEAN,
377 Name: [PATH_MAX_WIDE]WCHAR,
378
379 pub const WAIT_FOREVER: LARGE_INTEGER = std.math.minInt(LARGE_INTEGER);
380
381 pub fn init(opts: struct {
382 Timeout: ?LARGE_INTEGER = null,
383 Name: []const WCHAR,
384 }) WAIT_FOR_BUFFER {
385 var fpwfb: WAIT_FOR_BUFFER = .{
386 .Timeout = opts.Timeout orelse undefined,
387 .NameLength = @intCast(@sizeOf(WCHAR) * opts.Name.len),
388 .TimeoutSpecified = @intFromBool(opts.Timeout != null),
389 .Name = undefined,
390 };
391 @memcpy(fpwfb.Name[0..opts.Name.len], opts.Name);
392 return fpwfb;
393 }
394
395 pub fn getName(fpwfb: *const WAIT_FOR_BUFFER) []const WCHAR {
396 return fpwfb.Name[0..@divExact(fpwfb.NameLength, @sizeOf(WCHAR))];
397 }
398
399 pub fn toBuffer(fpwfb: *const WAIT_FOR_BUFFER) []const u8 {
400 const start: [*]const u8 = @ptrCast(fpwfb);
401 return start[0 .. @offsetOf(WAIT_FOR_BUFFER, "Name") + fpwfb.NameLength];
402 }
403 };
404 };
405
406 pub const ALL_INFORMATION = extern struct {
407 BasicInformation: BASIC_INFORMATION,
408 StandardInformation: STANDARD_INFORMATION,
409 InternalInformation: INTERNAL_INFORMATION,
410 EaInformation: EA_INFORMATION,
411 AccessInformation: ACCESS_INFORMATION,
412 PositionInformation: POSITION_INFORMATION,
413 ModeInformation: MODE.INFORMATION,
414 AlignmentInformation: ALIGNMENT_INFORMATION,
415 NameInformation: NAME_INFORMATION,
416 };
417
418 pub const INTERNAL_INFORMATION = extern struct {
419 IndexNumber: LARGE_INTEGER,
420 };
421
422 pub const EA_INFORMATION = extern struct {
423 EaSize: ULONG,
424 };
425
426 pub const ACCESS_INFORMATION = extern struct {
427 AccessFlags: ACCESS_MASK,
428 };
429
430 /// This is not separated into RENAME_INFORMATION and RENAME_INFORMATION_EX because
431 /// the only difference is the `Flags` type (BOOLEAN before _EX, ULONG in the _EX),
432 /// which doesn't affect the struct layout--the offset of RootDirectory is the same
433 /// regardless.
434 pub const RENAME_INFORMATION = extern struct {
435 Flags: FLAGS,
436 RootDirectory: ?HANDLE,
437 FileNameLength: ULONG,
438 FileName: [PATH_MAX_WIDE]WCHAR,
439
440 pub fn init(opts: struct {
441 Flags: FLAGS = .{},
442 RootDirectory: ?HANDLE = null,
443 FileName: []const WCHAR,
444 }) RENAME_INFORMATION {
445 var fri: RENAME_INFORMATION = .{
446 .Flags = opts.Flags,
447 .RootDirectory = opts.RootDirectory,
448 .FileNameLength = @intCast(@sizeOf(WCHAR) * opts.FileName.len),
449 .FileName = undefined,
450 };
451 @memcpy(fri.FileName[0..opts.FileName.len], opts.FileName);
452 return fri;
453 }
454
455 pub const FLAGS = packed struct(ULONG) {
456 REPLACE_IF_EXISTS: bool = false,
457 POSIX_SEMANTICS: bool = false,
458 SUPPRESS_PIN_STATE_INHERITANCE: bool = false,
459 SUPPRESS_STORAGE_RESERVE_INHERITANCE: bool = false,
460 AVAILABLE_SPACE: enum(u2) {
461 NO_PRESERVE = 0b00,
462 NO_INCREASE = 0b01,
463 NO_DECREASE = 0b10,
464 PRESERVE = 0b11,
465 } = .NO_PRESERVE,
466 IGNORE_READONLY_ATTRIBUTE: bool = false,
467 RESIZE_SR: enum(u2) {
468 NO_FORCE = 0b00,
469 FORCE_TARGET = 0b01,
470 FORCE_SOURCE = 0b10,
471 FORCE = 0b11,
472 } = .NO_FORCE,
473 Reserved9: u23 = 0,
474 };
475
476 pub fn getFileName(ri: *const RENAME_INFORMATION) []const WCHAR {
477 return ri.FileName[0..@divExact(ri.FileNameLength, @sizeOf(WCHAR))];
478 }
479
480 pub fn toBuffer(fri: *RENAME_INFORMATION) []u8 {
481 const start: [*]u8 = @ptrCast(fri);
482 // The ABI size of the documented struct is 24 bytes, and attempting to use any size
483 // less than that will trigger INFO_LENGTH_MISMATCH, so enforce a minimum in cases where,
484 // for example, FileNameLength is 1 so only 22 bytes are technically needed.
485 const size = @max(24, @offsetOf(RENAME_INFORMATION, "FileName") + fri.FileNameLength);
486 return start[0..size];
487 }
488 };
489
490 // ref: km/wdm.h
491
492 pub const INFORMATION_CLASS = enum(c_int) {
493 Directory = 1,
494 FullDirectory = 2,
495 BothDirectory = 3,
496 Basic = 4,
497 Standard = 5,
498 Internal = 6,
499 Ea = 7,
500 Access = 8,
501 Name = 9,
502 Rename = 10,
503 Link = 11,
504 Names = 12,
505 Disposition = 13,
506 Position = 14,
507 FullEa = 15,
508 Mode = 16,
509 Alignment = 17,
510 All = 18,
511 Allocation = 19,
512 EndOfFile = 20,
513 AlternateName = 21,
514 Stream = 22,
515 Pipe = 23,
516 PipeLocal = 24,
517 PipeRemote = 25,
518 MailslotQuery = 26,
519 MailslotSet = 27,
520 Compression = 28,
521 ObjectId = 29,
522 Completion = 30,
523 MoveCluster = 31,
524 Quota = 32,
525 ReparsePoint = 33,
526 NetworkOpen = 34,
527 AttributeTag = 35,
528 Tracking = 36,
529 IdBothDirectory = 37,
530 IdFullDirectory = 38,
531 ValidDataLength = 39,
532 ShortName = 40,
533 IoCompletionNotification = 41,
534 IoStatusBlockRange = 42,
535 IoPriorityHint = 43,
536 SfioReserve = 44,
537 SfioVolume = 45,
538 HardLink = 46,
539 ProcessIdsUsingFile = 47,
540 NormalizedName = 48,
541 NetworkPhysicalName = 49,
542 IdGlobalTxDirectory = 50,
543 IsRemoteDevice = 51,
544 Unused = 52,
545 NumaNode = 53,
546 StandardLink = 54,
547 RemoteProtocol = 55,
548 RenameBypassAccessCheck = 56,
549 LinkBypassAccessCheck = 57,
550 VolumeName = 58,
551 Id = 59,
552 IdExtdDirectory = 60,
553 ReplaceCompletion = 61,
554 HardLinkFullId = 62,
555 IdExtdBothDirectory = 63,
556 DispositionEx = 64,
557 RenameEx = 65,
558 RenameExBypassAccessCheck = 66,
559 DesiredStorageClass = 67,
560 Stat = 68,
561 MemoryPartition = 69,
562 StatLx = 70,
563 CaseSensitive = 71,
564 LinkEx = 72,
565 LinkExBypassAccessCheck = 73,
566 StorageReserveId = 74,
567 CaseSensitiveForceAccessCheck = 75,
568 KnownFolder = 76,
569 StatBasic = 77,
570 Id64ExtdDirectory = 78,
571 Id64ExtdBothDirectory = 79,
572 IdAllExtdDirectory = 80,
573 IdAllExtdBothDirectory = 81,
574 StreamReservation = 82,
575 MupProvider = 83,
576 _,
577
578 pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".field_names.len;
579 };
580
581 pub const BASIC_INFORMATION = extern struct {
582 CreationTime: LARGE_INTEGER,
583 LastAccessTime: LARGE_INTEGER,
584 LastWriteTime: LARGE_INTEGER,
585 ChangeTime: LARGE_INTEGER,
586 FileAttributes: ATTRIBUTE,
587 };
588
589 pub const STANDARD_INFORMATION = extern struct {
590 AllocationSize: LARGE_INTEGER,
591 EndOfFile: LARGE_INTEGER,
592 NumberOfLinks: ULONG,
593 DeletePending: BOOLEAN,
594 Directory: BOOLEAN,
595 };
596
597 pub const POSITION_INFORMATION = extern struct {
598 CurrentByteOffset: LARGE_INTEGER,
599 };
600
601 pub const FULL_EA_INFORMATION = extern struct {
602 NextEntryOffset: ULONG,
603 Flags: UCHAR,
604 EaNameLength: UCHAR,
605 EaValueLength: USHORT,
606 EaName: [0]CHAR,
607 };
608
609 pub const FS_DEVICE_INFORMATION = extern struct {
610 DeviceType: DEVICE_TYPE,
611 Characteristics: ULONG,
612 };
613
614 pub const USE_FILE_POINTER_POSITION = -2;
615
616 // ref: um/WinBase.h
617
618 pub const ATTRIBUTE_TAG_INFO = extern struct {
619 FileAttributes: DWORD,
620 ReparseTag: IO_REPARSE_TAG,
621 };
622
623 // ref: um/winnt.h
624
625 pub const SHARE = packed struct(ULONG) {
626 /// The file can be opened for read access by other threads.
627 READ: bool = false,
628 /// The file can be opened for write access by other threads.
629 WRITE: bool = false,
630 /// The file can be opened for delete access by other threads.
631 DELETE: bool = false,
632 Reserved3: u29 = 0,
633
634 pub const VALID_FLAGS: SHARE = .{
635 .READ = true,
636 .WRITE = true,
637 .DELETE = true,
638 };
639 };
640
641 pub const ATTRIBUTE = packed struct(ULONG) {
642 /// The file is read only. Applications can read the file, but cannot write to or delete it.
643 READONLY: bool = false,
644 /// The file is hidden. Do not include it in an ordinary directory listing.
645 HIDDEN: bool = false,
646 /// The file is part of or used exclusively by an operating system.
647 SYSTEM: bool = false,
648 Reserved3: u1 = 0,
649 DIRECTORY: bool = false,
650 /// The file should be archived. Applications use this attribute to mark files for backup or removal.
651 ARCHIVE: bool = false,
652 DEVICE: bool = false,
653 /// The file does not have other attributes set. This attribute is valid only if used alone.
654 NORMAL: bool = false,
655 /// The file is being used for temporary storage.
656 TEMPORARY: bool = false,
657 SPARSE_FILE: bool = false,
658 REPARSE_POINT: bool = false,
659 COMPRESSED: bool = false,
660 /// The data of a file is not immediately available. This attribute indicates that file data is physically moved to offline storage.
661 /// This attribute is used by Remote Storage, the hierarchical storage management software. Applications should not arbitrarily change this attribute.
662 OFFLINE: bool = false,
663 NOT_CONTENT_INDEXED: bool = false,
664 /// 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
665 /// the default for newly created files and subdirectories. For more information, see File Encryption.
666 ///
667 /// This flag has no effect if `SYSTEM` is also specified.
668 ///
669 /// This flag is not supported on Home, Home Premium, Starter, or ARM editions of Windows.
670 ENCRYPTED: bool = false,
671 INTEGRITY_STREAM: bool = false,
672 VIRTUAL: bool = false,
673 NO_SCRUB_DATA: bool = false,
674 EA_or_RECALL_ON_OPEN: bool = false,
675 PINNED: bool = false,
676 UNPINNED: bool = false,
677 Reserved21: u1 = 0,
678 RECALL_ON_DATA_ACCESS: bool = false,
679 Reserved23: u6 = 0,
680 STRICTLY_SEQUENTIAL: bool = false,
681 Reserved30: u2 = 0,
682 };
683
684 // ref: um/winternl.h
685
686 /// Define the create disposition values
687 pub const CREATE_DISPOSITION = enum(ULONG) {
688 /// If the file already exists, replace it with the given file. If it does not, create the given file.
689 SUPERSEDE = 0x00000000,
690 /// If the file already exists, open it instead of creating a new file.
691 /// If it does not, fail the request and do not create a new file.
692 OPEN = 0x00000001,
693 /// If the file already exists, fail the request and do not create or
694 /// open the given file. If it does not, create the given file.
695 CREATE = 0x00000002,
696 /// If the file already exists, open it. If it does not, create the given file.
697 OPEN_IF = 0x00000003,
698 /// If the file already exists, open it and overwrite it. If it does not, fail the request.
699 OVERWRITE = 0x00000004,
700 /// If the file already exists, open it and overwrite it. If it does not, create the given file.
701 OVERWRITE_IF = 0x00000005,
702
703 pub const MAXIMUM_DISPOSITION: CREATE_DISPOSITION = .OVERWRITE_IF;
704 };
705
706 /// Define the create/open option flags
707 pub const MODE = packed struct(ULONG) {
708 /// The file being created or opened is a directory file. With this
709 /// flag, the CreateDisposition parameter must be set to `.CREATE`,
710 /// `.FILE_OPEN`, or `.OPEN_IF`. With this flag, other compatible
711 /// CreateOptions flags include only the following: `SYNCHRONOUS_IO`,
712 /// `WRITE_THROUGH`, `OPEN_FOR_BACKUP_INTENT`, and `OPEN_BY_FILE_ID`.
713 DIRECTORY_FILE: bool = false,
714 /// Applications that write data to the file must actually transfer the
715 /// data into the file before any requested write operation is
716 /// considered complete. This flag is automatically set if the
717 /// CreateOptions flag `NO_INTERMEDIATE_BUFFERING` is set.
718 WRITE_THROUGH: bool = false,
719 /// All accesses to the file are sequential.
720 SEQUENTIAL_ONLY: bool = false,
721 /// The file cannot be cached or buffered in a driver's internal
722 /// buffers. This flag is incompatible with the DesiredAccess
723 /// `FILE_APPEND_DATA` flag.
724 NO_INTERMEDIATE_BUFFERING: bool = false,
725 IO: enum(u2) {
726 /// All operations on the file are performed asynchronously.
727 ASYNCHRONOUS = 0b00,
728 /// All operations on the file are performed synchronously. Any
729 /// wait on behalf of the caller is subject to premature
730 /// termination from alerts. This flag also causes the I/O system
731 /// to maintain the file position context. If this flag is set, the
732 /// DesiredAccess `SYNCHRONIZE` flag also must be set.
733 SYNCHRONOUS_ALERT = 0b01,
734 /// All operations on the file are performed synchronously. Waits
735 /// in the system to synchronize I/O queuing and completion are not
736 /// subject to alerts. This flag also causes the I/O system to
737 /// maintain the file position context. If this flag is set, the
738 /// DesiredAccess `SYNCHRONIZE` flag also must be set.
739 SYNCHRONOUS_NONALERT = 0b10,
740 _,
741
742 pub const VALID_FLAGS: @This() = @fromBackingInt(@intCast(0b11));
743 },
744 /// The file being opened must not be a directory file or this call
745 /// fails. The file object being opened can represent a data file, a
746 /// logical, virtual, or physical device, or a volume.
747 NON_DIRECTORY_FILE: bool = false,
748 /// Create a tree connection for this file in order to open it over the
749 /// network. This flag is not used by device and intermediate drivers.
750 CREATE_TREE_CONNECTION: bool = false,
751 /// Complete this operation immediately with an alternate success code
752 /// of `STATUS_OPLOCK_BREAK_IN_PROGRESS` if the target file is
753 /// oplocked, rather than blocking the caller's thread. If the file is
754 /// oplocked, another caller already has access to the file. This flag
755 /// is not used by device and intermediate drivers.
756 COMPLETE_IF_OPLOCKED: bool = false,
757 /// If the extended attributes on an existing file being opened
758 /// indicate that the caller must understand EAs to properly interpret
759 /// the file, fail this request because the caller does not understand
760 /// how to deal with EAs. This flag is irrelevant for device and
761 /// intermediate drivers.
762 NO_EA_KNOWLEDGE: bool = false,
763 OPEN_REMOTE_INSTANCE: bool = false,
764 /// Accesses to the file can be random, so no sequential read-ahead
765 /// operations should be performed on the file by FSDs or the system.
766 RANDOM_ACCESS: bool = false,
767 /// Delete the file when the last handle to it is passed to `NtClose`.
768 /// If this flag is set, the `DELETE` flag must be set in the
769 /// DesiredAccess parameter.
770 DELETE_ON_CLOSE: bool = false,
771 /// The file name that is specified by the `ObjectAttributes` parameter
772 /// includes the 8-byte file reference number for the file. This number
773 /// is assigned by and specific to the particular file system. If the
774 /// file is a reparse point, the file name will also include the name
775 /// of a device. Note that the FAT file system does not support this
776 /// flag. This flag is not used by device and intermediate drivers.
777 OPEN_BY_FILE_ID: bool = false,
778 /// The file is being opened for backup intent. Therefore, the system
779 /// should check for certain access rights and grant the caller the
780 /// appropriate access to the file before checking the DesiredAccess
781 /// parameter against the file's security descriptor. This flag not
782 /// used by device and intermediate drivers.
783 OPEN_FOR_BACKUP_INTENT: bool = false,
784 /// Suppress inheritance of `FILE_ATTRIBUTE.COMPRESSED` from the parent
785 /// directory. This allows creation of a non-compressed file in a
786 /// directory that is marked compressed.
787 NO_COMPRESSION: bool = false,
788 /// The file is being opened and an opportunistic lock on the file is
789 /// being requested as a single atomic operation. The file system
790 /// checks for oplocks before it performs the create operation and will
791 /// fail the create with a return code of STATUS_CANNOT_BREAK_OPLOCK if
792 /// the result would be to break an existing oplock. For more
793 /// information, see the Remarks section.
794 ///
795 /// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows
796 /// XP: This flag is not supported.
797 ///
798 /// This flag is supported on the following file systems: NTFS, FAT,
799 /// and exFAT.
800 OPEN_REQUIRING_OPLOCK: bool = false,
801 Reserved17: u3 = 0,
802 /// This flag allows an application to request a filter opportunistic
803 /// lock to prevent other applications from getting share violations.
804 /// If there are already open handles, the create request will fail
805 /// with STATUS_OPLOCK_NOT_GRANTED. For more information, see the
806 /// Remarks section.
807 RESERVE_OPFILTER: bool = false,
808 /// Open a file with a reparse point and bypass normal reparse point
809 /// processing for the file. For more information, see the Remarks
810 /// section.
811 OPEN_REPARSE_POINT: bool = false,
812 /// Instructs any filters that perform offline storage or
813 /// virtualization to not recall the contents of the file as a result
814 /// of this open.
815 OPEN_NO_RECALL: bool = false,
816 /// This flag instructs the file system to capture the user associated
817 /// with the calling thread. Any subsequent calls to
818 /// `FltQueryVolumeInformation` or `ZwQueryVolumeInformationFile` using
819 /// the returned handle will assume the captured user, rather than the
820 /// calling user at the time, for purposes of computing the free space
821 /// available to the caller. This applies to the following
822 /// FsInformationClass values: `FileFsSizeInformation`,
823 /// `FileFsFullSizeInformation`, and `FileFsFullSizeInformationEx`.
824 OPEN_FOR_FREE_SPACE_QUERY: bool = false,
825 Reserved24: u8 = 0,
826
827 pub const VALID_OPTION_FLAGS: MODE = .{
828 .DIRECTORY_FILE = true,
829 .WRITE_THROUGH = true,
830 .SEQUENTIAL_ONLY = true,
831 .NO_INTERMEDIATE_BUFFERING = true,
832 .IO = .VALID_FLAGS,
833 .NON_DIRECTORY_FILE = true,
834 .CREATE_TREE_CONNECTION = true,
835 .COMPLETE_IF_OPLOCKED = true,
836 .NO_EA_KNOWLEDGE = true,
837 .OPEN_REMOTE_INSTANCE = true,
838 .RANDOM_ACCESS = true,
839 .DELETE_ON_CLOSE = true,
840 .OPEN_BY_FILE_ID = true,
841 .OPEN_FOR_BACKUP_INTENT = true,
842 .NO_COMPRESSION = true,
843 .OPEN_REQUIRING_OPLOCK = true,
844 .Reserved17 = 0b111,
845 .RESERVE_OPFILTER = true,
846 .OPEN_REPARSE_POINT = true,
847 .OPEN_NO_RECALL = true,
848 .OPEN_FOR_FREE_SPACE_QUERY = true,
849 };
850
851 pub const VALID_PIPE_OPTION_FLAGS: MODE = .{
852 .WRITE_THROUGH = true,
853 .IO = .VALID_FLAGS,
854 };
855
856 pub const VALID_MAILSLOT_OPTION_FLAGS: MODE = .{
857 .WRITE_THROUGH = true,
858 .IO = .VALID_FLAGS,
859 };
860
861 pub const VALID_SET_OPTION_FLAGS: MODE = .{
862 .WRITE_THROUGH = true,
863 .SEQUENTIAL_ONLY = true,
864 .IO = .VALID_FLAGS,
865 };
866
867 // ref: km/ntifs.h
868
869 pub const INFORMATION = extern struct {
870 /// The set of flags that specify the mode in which the file can be
871 /// accessed. These flags are a subset of `MODE`.
872 Mode: MODE,
873 };
874 };
875};
876
877pub const DIRECTORY = struct {
878 pub const NOTIFY_INFORMATION_CLASS = enum(c_int) {
879 Notify = 1,
880 NotifyExtended = 2,
881 NotifyFull = 3,
882 _,
883
884 pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".field_names.len;
885 };
886};
887
888pub const CONSOLE = struct {
889 pub const USER_IO = struct {
890 pub const INFO = struct {
891 pub const CP = extern struct {
892 /// GetCP: output
893 /// SetCP: input
894 CodePage: UINT,
895 /// input
896 Mode: MODE,
897
898 pub const MODE = enum(BOOLEAN.Backing) {
899 Input,
900 Output,
901 };
902 };
903
904 pub const WRITE = extern struct {
905 /// output, in bytes
906 Size: DWORD,
907 /// input
908 Mode: MODE,
909
910 pub const MODE = enum(BOOLEAN.Backing) {
911 Character,
912 WideCharacter,
913 };
914 };
915
916 pub const FILL = extern struct {
917 /// input
918 dwWriteCoord: COORD,
919 /// input
920 Tag: WITH.Tag,
921 /// input
922 With: WITH.Payload,
923 /// input/output, in characters
924 nLength: DWORD,
925
926 pub const WITH = union(enum(DWORD)) {
927 Character: CHAR = 1,
928 WideCharacter: WCHAR = 2,
929 Attribute: WORD = 3,
930
931 pub const Tag = @typeInfo(WITH).@"union".tag_type.?;
932 pub const Payload = PAYLOAD: {
933 const with_info = @typeInfo(WITH).@"union";
934 break :PAYLOAD @Union(.@"extern", null, with_info.field_names, with_info.field_types[0..], &@splat(.{}));
935 };
936 };
937 };
938
939 /// all output
940 pub const SCREEN_BUFFER = extern struct {
941 dwSize: COORD,
942 dwCursorPosition: COORD,
943 dwWindowPosition: COORD,
944 wAttributes: WORD,
945 dwWindowSize: COORD,
946 dwMaximumWindowSize: COORD,
947 wPopupAttributes: WORD,
948 bFullscreenSupported: BOOL,
949 ColorTable: [16]COLORREF,
950 };
951
952 pub const READ_OUTPUT_CHARACTER = extern struct {
953 /// input
954 dwReadCoord: COORD,
955 Mode: MODE,
956 /// output, in characters
957 nLength: DWORD,
958
959 pub const MODE = enum(DWORD) {
960 Character = 1,
961 WideCharacter = 2,
962 };
963 };
964 };
965
966 pub fn GET_CP(mode: INFO.CP.MODE) Header.With(INFO.CP) {
967 return .init(.GetCP, .{ .CodePage = undefined, .Mode = mode });
968 }
969 pub const GET_MODE: Header.With(DWORD) = .init(.GetMode, undefined);
970 pub fn SET_MODE(mode: DWORD) Header.With(DWORD) {
971 return .init(.SetMode, mode);
972 }
973 pub fn WRITE(mode: INFO.WRITE.MODE) Header.With(INFO.WRITE) {
974 return .init(.Write, .{ .Size = undefined, .Mode = mode });
975 }
976 pub fn FILL(with: INFO.FILL.WITH, len: DWORD, coord: COORD) Header.With(INFO.FILL) {
977 return .init(.Fill, .{
978 .dwWriteCoord = coord,
979 .Tag = with,
980 .With = switch (with) {
981 inline else => |payload, tag| @unionInit(
982 INFO.FILL.WITH.Payload,
983 @tagName(tag),
984 payload,
985 ),
986 },
987 .nLength = len,
988 });
989 }
990 pub fn SET_CP(mode: INFO.CP.MODE, cp: UINT) Header.With(INFO.CP) {
991 return .init(.SetCP, .{ .CodePage = cp, .Mode = mode });
992 }
993 pub const GET_SCREEN_BUFFER_INFO: Header.With(INFO.SCREEN_BUFFER) =
994 .init(.GetScreenBufferInfo, undefined);
995 pub fn SET_CURSOR_POSITION(coord: COORD) Header.With(COORD) {
996 return .init(.SetCursorPosition, coord);
997 }
998 pub fn SET_TEXT_ATTRIBUTE(attribute: WORD) Header.With(WORD) {
999 return .init(.SetTextAttribute, attribute);
1000 }
1001 pub fn READ_OUTPUT_CHARACTER(
1002 coord: COORD,
1003 mode: INFO.READ_OUTPUT_CHARACTER.MODE,
1004 ) Header.With(INFO.READ_OUTPUT_CHARACTER) {
1005 return .init(.ReadOutputCharacter, .{
1006 .dwReadCoord = coord,
1007 .Mode = mode,
1008 .nLength = undefined,
1009 });
1010 }
1011
1012 pub const InputBuffer = extern struct {
1013 Size: u32,
1014 Pointer: *const anyopaque,
1015 };
1016
1017 pub const OutputBuffer = extern struct {
1018 Size: u32,
1019 Pointer: *anyopaque,
1020 };
1021
1022 pub fn Request(comptime in_len: u32, comptime out_len: u32) type {
1023 return extern struct {
1024 Handle: ?HANDLE,
1025 InputBuffersLength: u32,
1026 OutputBuffersLength: u32,
1027 InputBuffers: [in_len]InputBuffer,
1028 OutputBuffers: [out_len]OutputBuffer,
1029
1030 pub fn init(
1031 handle: ?HANDLE,
1032 in: [in_len]InputBuffer,
1033 out: [out_len]OutputBuffer,
1034 ) @This() {
1035 return .{
1036 .Handle = handle,
1037 .InputBuffersLength = in_len,
1038 .OutputBuffersLength = out_len,
1039 .InputBuffers = in,
1040 .OutputBuffers = out,
1041 };
1042 }
1043 };
1044 }
1045
1046 pub const Header = extern struct {
1047 Operation: Operation,
1048 Size: u32,
1049
1050 pub fn With(comptime Data: type) type {
1051 return extern struct {
1052 Header: Header,
1053 Data: Data,
1054
1055 pub fn init(operation: Operation, data: Data) @This() {
1056 return .{
1057 .Header = .{ .Operation = operation, .Size = @sizeOf(Data) },
1058 .Data = data,
1059 };
1060 }
1061
1062 pub fn request(
1063 with: *@This(),
1064 file: ?Io.File,
1065 comptime in_len: u32,
1066 in: [in_len]InputBuffer,
1067 comptime out_len: u32,
1068 out: [out_len]OutputBuffer,
1069 ) Request(1 + in_len, 1 + out_len) {
1070 return .init(
1071 if (file) |f| f.handle else null,
1072 [1]InputBuffer{.{
1073 .Size = @offsetOf(@This(), "Data") + @sizeOf(Data),
1074 .Pointer = with,
1075 }} ++ in,
1076 [1]OutputBuffer{.{ .Size = @sizeOf(Data), .Pointer = &with.Data }} ++ out,
1077 );
1078 }
1079
1080 pub fn operate(with: *@This(), io: Io, file: ?Io.File) Io.Cancelable!NTSTATUS {
1081 return (try io.operate(.{ .device_io_control = .{
1082 .file = .{
1083 .handle = peb().ProcessParameters.ConsoleHandle,
1084 .flags = .{ .nonblocking = false },
1085 },
1086 .code = IOCTL.CONDRV.ISSUE_USER_IO,
1087 .in = @ptrCast(&with.request(file, 0, .{}, 0, .{})),
1088 } })).device_io_control.u.Status;
1089 }
1090 };
1091 }
1092 };
1093
1094 pub const Operation = enum(u32) {
1095 GetCP = 0x1000000,
1096 GetMode = 0x1000001,
1097 SetMode = 0x1000002,
1098 Read = 0x1000005,
1099 Write = 0x1000006,
1100 Fill = 0x2000000,
1101 SetCP = 0x2000004,
1102 GetScreenBufferInfo = 0x2000007,
1103 SetCursorPosition = 0x200000a,
1104 SetTextAttribute = 0x200000d,
1105 ReadOutputCharacter = 0x200000f,
1106 _,
1107 };
1108 };
1109};
1110
1111pub const AFD = packed struct(ULONG) {
1112 NO_FAST_IO: bool = false,
1113 OVERLAPPED: bool = false,
1114 Reserved0: u30 = 0,
1115
1116 pub const Mutability = enum { @"const", @"var" };
1117 pub fn WSABUF(comptime mutability: Mutability) type {
1118 return extern struct {
1119 len: ULONG,
1120 buf: switch (mutability) {
1121 .@"const" => [*]const u8,
1122 .@"var" => [*]u8,
1123 },
1124 };
1125 }
1126 pub const GUARANTEE = enum(c_int) {
1127 BestEffort,
1128 ControlledLoad,
1129 Predictive,
1130 GuaranteedDelay,
1131 Guaranteed,
1132 _,
1133 };
1134 pub const DEVICE_NAME: []const u16 = &.{ '\\', 'D', 'e', 'v', 'i', 'c', 'e', '\\', 'A', 'f', 'd' };
1135 pub const ENDPOINT_TYPE = packed struct(ULONG) {
1136 CONNECTIONLESS: bool = false,
1137 Reserved1: u3 = 0,
1138 MESSAGEMODE: bool = false,
1139 Reserved5: u3 = 0,
1140 RAW: bool = false,
1141 Reserved9: u22 = 0,
1142 REGISTERED_IO: bool = false,
1143 };
1144 pub const OPEN_PACKET = extern struct {
1145 EndpointType: ENDPOINT_TYPE,
1146 GroupID: LONG,
1147 AddressFamily: LONG,
1148 SocketType: LONG,
1149 Protocol: LONG,
1150 TransportDeviceNameLength: ULONG,
1151 TransportDeviceName: [1]WCHAR,
1152
1153 pub const NAME = "AfdOpenPacketXX";
1154
1155 pub const FULL_EA_INFORMATION = extern struct {
1156 Header: FILE.FULL_EA_INFORMATION = .{
1157 .NextEntryOffset = 0,
1158 .Flags = 0,
1159 .EaNameLength = NAME.len,
1160 .EaValueLength = @sizeOf(OPEN_PACKET),
1161 .EaName = .{},
1162 },
1163 Name: [NAME.len:0]u8 = NAME.*,
1164 Value: OPEN_PACKET,
1165 };
1166 };
1167 pub const BIND_INFO = extern struct {
1168 Mode: MODE,
1169
1170 pub const MODE = enum(ULONG) {
1171 Unix = 0,
1172 Passive = 1,
1173 Active = 2,
1174 _,
1175 };
1176 };
1177 pub const LISTEN_INFO = extern struct {
1178 UseSAN: BOOLEAN,
1179 MaximumConnectionQueue: ULONG,
1180 UseDelayedAcceptance: BOOLEAN,
1181 };
1182 pub const LISTEN_RESPONSE_INFO = extern struct {
1183 Sequence: ULONG,
1184 };
1185 pub const ACCEPT_INFO = extern struct {
1186 UseSAN: BOOLEAN,
1187 Sequence: ULONG,
1188 AcceptHandle: HANDLE,
1189 };
1190 pub const SUPER_ACCEPT_INFO = extern struct {
1191 UseSAN: BOOLEAN,
1192 AcceptHandle: HANDLE,
1193 AcceptEndpoint: PVOID,
1194 AcceptFileObject: PVOID,
1195 ReceiveDataLength: ULONG,
1196 LocalAddressLength: ULONG,
1197 RemoteAddressLength: ULONG,
1198 ListenResponseInfo: LISTEN_RESPONSE_INFO,
1199 };
1200 pub const DEFER_ACCEPT_INFO = extern struct {
1201 Sequence: ULONG,
1202 Reject: BOOLEAN,
1203 };
1204 pub const PARTIAL_DISCONNECT_INFO = extern struct {
1205 DisconnectMode: MODE,
1206 Timeout: LARGE_INTEGER,
1207
1208 pub const MODE = packed struct(ULONG) {
1209 SEND: bool = false,
1210 RECEIVE: bool = false,
1211 ABORTIVE: bool = false,
1212 UNCONNECT_DATAGRAM: bool = false,
1213 Reserved4: u28 = 0,
1214 };
1215 };
1216 pub const RECEIVE_INFORMATION = extern struct {
1217 BytesAvailable: ULONG,
1218 ExpeditedBytesAvailable: ULONG,
1219 };
1220 pub const HANDLE_INFO = extern struct {
1221 TdiAddressHandle: HANDLE,
1222 TdiConnectionHandle: HANDLE,
1223 };
1224 pub const INFORMATION = extern struct {
1225 InformationType: TYPE,
1226 Information: extern union {
1227 Boolean: BOOLEAN,
1228 Ulong: ULONG,
1229 LargeInteger: LARGE_INTEGER,
1230 },
1231
1232 pub const TYPE = enum(ULONG) {
1233 INLINE_MODE = 0x01,
1234 NONBLOCKING_MODE = 0x02,
1235 MAX_SEND_SIZE = 0x03,
1236 SENDS_PENDING = 0x04,
1237 MAX_PATH_SEND_SIZE = 0x05,
1238 RECEIVE_WINDOW_SIZE = 0x06,
1239 SEND_WINDOW_SIZE = 0x07,
1240 CONNECT_TIME = 0x08,
1241 CIRCULAR_QUEUEING = 0x09,
1242 GROUP_ID_AND_TYPE = 0x0A,
1243 _,
1244 };
1245 };
1246 pub const TRANSMIT_FILE_INFO = extern struct {
1247 Offset: LARGE_INTEGER,
1248 WriteLength: LARGE_INTEGER,
1249 SendPacketLength: ULONG,
1250 FileHandle: HANDLE,
1251 Head: PVOID,
1252 HeadLength: ULONG,
1253 Tail: PVOID,
1254 TailLength: ULONG,
1255 Flags: FLAGS,
1256
1257 pub const FLAGS = packed struct(ULONG) {
1258 DISCONNECT: bool = false,
1259 REUSE_SOCKET: bool = false,
1260 WRITE_BEHIND: bool = false,
1261 Reserved3: u25 = 0,
1262 };
1263 };
1264 pub const QUEUE_APC_INFO = extern struct {
1265 Thread: HANDLE,
1266 ApcRoutine: PVOID,
1267 ApcContext: PVOID,
1268 SystemArgument1: PVOID,
1269 SystemArgument2: PVOID,
1270 };
1271 pub const SEND_INFO = extern struct {
1272 BufferArray: [*]const WSABUF(.@"const"),
1273 BufferCount: ULONG,
1274 AfdFlags: AFD,
1275 TdiFlags: TDI.SEND,
1276 };
1277 pub const SEND_DATAGRAM_INFO = extern struct {
1278 BufferArray: [*]const WSABUF(.@"const"),
1279 BufferCount: ULONG,
1280 AfdFlags: AFD,
1281 TdiRequest: TDI.REQUEST.SEND_DATAGRAM,
1282 TdiConnInfo: TDI.CONNECTION.INFORMATION,
1283 };
1284 pub const RECV_INFO = extern struct {
1285 BufferArray: [*]const WSABUF(.@"var"),
1286 BufferCount: ULONG,
1287 AfdFlags: AFD,
1288 TdiFlags: TDI.RECEIVE,
1289 };
1290 pub const RECV_DATAGRAM_INFO = extern struct {
1291 BufferArray: [*]const WSABUF(.@"var"),
1292 BufferCount: ULONG,
1293 AfdFlags: AFD,
1294 TdiFlags: TDI.RECEIVE,
1295 Address: PVOID,
1296 AddressLength: *ULONG,
1297 };
1298 pub const SOCKOPT_INFO = extern struct {
1299 mode: Mode,
1300 level: i32,
1301 optname: u32,
1302 ding: u32 = 1,
1303 optval: *const anyopaque,
1304 optlen: usize,
1305
1306 pub const Mode = enum(u32) { set = 1, get = 2, special = 3, _ };
1307
1308 pub const UNIX_PATH = extern struct { Unknown0: usize = 0, Path: [PATH_MAX_WIDE:0]u16 };
1309 };
1310};
1311
1312pub const TDI = struct {
1313 pub const STATUS = NTSTATUS;
1314 pub const CONNECTION = struct {
1315 pub const CONTEXT = PVOID;
1316 pub const INFORMATION = extern struct {
1317 /// length of user data buffer
1318 UserDataLength: LONG,
1319 /// pointer to user data buffer
1320 UserData: PVOID,
1321 /// length of following buffer
1322 OptionsLength: LONG,
1323 /// pointer to buffer containing options
1324 Options: PVOID,
1325 /// length of following buffer
1326 RemoteAddressLength: LONG,
1327 /// buffer containing the remote address
1328 RemoteAddress: PVOID,
1329 };
1330 };
1331 pub const ADDRESS = struct {
1332 pub const TYPE = enum(USHORT) {
1333 /// unspecified
1334 UNSPEC = 0,
1335 /// local to host (pipes, portals,
1336 UNIX = 1,
1337 /// internetwork: UDP, TCP, etc.
1338 IP = 2,
1339 /// arpanet imp addresses
1340 IMPLINK = 3,
1341 /// pup protocols: e.g. BSP
1342 PUP = 4,
1343 /// mit CHAOS protocols
1344 CHAOS = 5,
1345 /// XEROX NS protocols
1346 NS = 6,
1347 /// Netware IPX
1348 IPX = 6,
1349 /// nbs protocols
1350 NBS = 7,
1351 /// european computer manufacturers
1352 ECMA = 8,
1353 /// datakit protocols
1354 DATAKIT = 9,
1355 /// CCITT protocols, X.25 etc
1356 CCITT = 10,
1357 /// IBM SNA
1358 SNA = 11,
1359 /// DECnet
1360 DECnet = 12,
1361 /// Direct data link interface
1362 DLI = 13,
1363 /// LAT
1364 LAT = 14,
1365 /// NSC Hyperchannel
1366 HYLINK = 15,
1367 /// AppleTalk
1368 APPLETALK = 16,
1369 /// Netbios Addresses
1370 NETBIOS = 17,
1371 @"8022" = 18,
1372 OSI_TSAP = 19,
1373 /// for WzMail
1374 NETONE = 20,
1375 /// Banyan VINES IP
1376 VNS = 21,
1377 /// NETBIOS address extensions
1378 NETBIOS_EX = 22,
1379 /// IP version 6
1380 IP6 = 23,
1381 /// WCHAR Netbios address
1382 NETBIOS_UNICODE_EX = 24,
1383 _,
1384 };
1385 pub const IP = extern struct {
1386 sin_port: USHORT,
1387 in_addr: ULONG,
1388 sin_zero: [8]UCHAR,
1389 };
1390 pub const IP6 = extern struct {
1391 sin_port: USHORT,
1392 flowinfo: ULONG,
1393 addr: [8]USHORT,
1394 scope_id: ULONG,
1395 };
1396 };
1397 pub const REQUEST = extern struct {
1398 Handle: extern union {
1399 AddressHandle: HANDLE,
1400 ConnectionContext: CONNECTION.CONTEXT,
1401 ControlChannel: HANDLE,
1402 },
1403 RequestNotifyObject: PVOID,
1404 RequestContext: PVOID,
1405 TdiStatus: TDI.STATUS,
1406
1407 pub const STATUS = extern struct {
1408 /// status of request completion
1409 Status: TDI.STATUS,
1410 /// the request context
1411 RequestContext: PVOID,
1412 /// number of bytes transferred in the request
1413 BytesTransferred: ULONG,
1414 };
1415 pub const ASSOCIATE = extern struct {
1416 Request: REQUEST,
1417 AddressHandle: HANDLE,
1418 };
1419 pub const CONNECT = extern struct {
1420 Request: REQUEST,
1421 RequestConnectionInformation: *CONNECTION.INFORMATION,
1422 ReturnConnectionInformation: *CONNECTION.INFORMATION,
1423 Timeout: LARGE_INTEGER,
1424 };
1425 pub const ACCEPT = extern struct {
1426 Request: REQUEST,
1427 RequestConnectionInformation: *CONNECTION.INFORMATION,
1428 ReturnConnectionInformation: *CONNECTION.INFORMATION,
1429 };
1430 pub const LISTEN = extern struct {
1431 Request: REQUEST,
1432 RequestConnectionInformation: *CONNECTION.INFORMATION,
1433 ReturnConnectionInformation: *CONNECTION.INFORMATION,
1434 ListenFlags: USHORT,
1435 };
1436 pub const DISCONNECT = extern struct {
1437 Request: REQUEST,
1438 Timeout: LARGE_INTEGER,
1439 };
1440 pub const SEND = extern struct {
1441 Request: REQUEST,
1442 SendFlags: USHORT,
1443 };
1444 pub const RECEIVE = extern struct {
1445 Request: REQUEST,
1446 ReceiveFlags: USHORT,
1447 };
1448 pub const SEND_DATAGRAM = extern struct {
1449 Request: REQUEST,
1450 SendDatagramInformation: *CONNECTION.INFORMATION,
1451 };
1452 };
1453 pub const RECEIVE = packed struct(ULONG) {
1454 Reserved0: u2 = 0,
1455 BROADCAST: bool = false,
1456 MULTICAST: bool = false,
1457 PARTIAL: bool = false,
1458 NORMAL: bool = false,
1459 EXPEDITED: bool = false,
1460 PEEK: bool = false,
1461 NO_RESPONSE_EXP: bool = false,
1462 COPY_LOOKAHEAD: bool = false,
1463 ENTIRE_MESSAGE: bool = false,
1464 AT_DISPATCH_LEVEL: bool = false,
1465 CONTROL_INFO: bool = false,
1466 FORCE_INDICATION: bool = false,
1467 NO_PUSH: bool = false,
1468 Reserved12: u17 = 0,
1469 };
1470 pub const SEND = packed struct(ULONG) {
1471 Reserved0: u5 = 0,
1472 EXPEDITED: bool = false,
1473 PARTIAL: bool = false,
1474 NO_RESPONSE_EXPECTED: bool = false,
1475 NON_BLOCKING: bool = false,
1476 AND_DISCONNECT: bool = false,
1477 Reserved10: u22 = 0,
1478 };
1479};
1480
1481pub const NET = struct {
1482 pub const LUID = packed struct(ULONG64) { Reserved: u24 = 0, Index: u24, IfType: u16 };
1483 pub const IFINDEX = enum(ULONG) { _ };
1484};
1485
1486pub const DNS = struct {
1487 pub const INTERFACE_SETTINGS = extern struct {
1488 Version: ULONG,
1489 Flags: ULONG64,
1490 Domain: PWSTR,
1491 NameServer: PWSTR,
1492 SearchList: PWSTR,
1493 RegistrationEnabled: ULONG,
1494 RegisterAdapterName: ULONG,
1495 EnableLLMNR: ULONG,
1496 QueryAdapterName: ULONG,
1497 ProfileNameServer: PWSTR,
1498 };
1499
1500 // ref: shared/windnsdef.h
1501
1502 pub const ADDR_MAX_SOCKADDR_LENGTH = 32;
1503
1504 pub const ADDR = extern struct {
1505 MaxSa: [ADDR_MAX_SOCKADDR_LENGTH]CHAR,
1506 DnsAddrUserDword: [8]DWORD,
1507
1508 pub const ARRAY = extern struct {
1509 MaxCount: DWORD,
1510 AddrCount: DWORD,
1511 Tag: DWORD,
1512 Family: WORD,
1513 WordReserved: WORD,
1514 Flags: DWORD,
1515 MatchFlag: DWORD,
1516 Reserved1: DWORD,
1517 Reserved2: DWORD,
1518 AddrArray: [0]ADDR,
1519 };
1520 };
1521
1522 pub const CUSTOM_SERVER = extern struct {
1523 ServerType: CUSTOM_SERVER.TYPE,
1524 Flags: FLAGS,
1525 Info: extern union {
1526 UDP: void,
1527 DOH: extern struct { Template: PWSTR },
1528 DOT: extern struct { Hostname: PWSTR },
1529 },
1530 MaxSa: [ADDR_MAX_SOCKADDR_LENGTH]CHAR,
1531
1532 pub const TYPE = enum(DWORD) { UDP = 0x1, DOH = 0x2, DOT = 0x3, _ };
1533 pub const FLAGS = packed struct(ULONG64) {
1534 UDP_FALLBACK: bool = false,
1535 UPGRADE_FROM_WELL_KNOWN_SERVERS: bool = false,
1536 Reserved2: u62 = 0,
1537 };
1538 };
1539
1540 // ref: um/WinDNS.h
1541
1542 pub const STATUS = Win32Error;
1543
1544 pub const TYPE = enum(WORD) {
1545 A = 0x0001,
1546 NS = 0x0002,
1547 MD = 0x0003,
1548 MF = 0x0004,
1549 CNAME = 0x0005,
1550 SOA = 0x0006,
1551 MB = 0x0007,
1552 MG = 0x0008,
1553 MR = 0x0009,
1554 NULL = 0x000a,
1555 WKS = 0x000b,
1556 PTR = 0x000c,
1557 HINFO = 0x000d,
1558 MINFO = 0x000e,
1559 MX = 0x000f,
1560 TEXT = 0x0010,
1561 RP = 0x0011,
1562 AFSDB = 0x0012,
1563 X25 = 0x0013,
1564 ISDN = 0x0014,
1565 RT = 0x0015,
1566 NSAP = 0x0016,
1567 NSAPPTR = 0x0017,
1568 SIG = 0x0018,
1569 KEY = 0x0019,
1570 PX = 0x001a,
1571 GPOS = 0x001b,
1572 AAAA = 0x001c,
1573 LOC = 0x001d,
1574 NXT = 0x001e,
1575 EID = 0x001f,
1576 NIMLOC = 0x0020,
1577 SRV = 0x0021,
1578 ATMA = 0x0022,
1579 NAPTR = 0x0023,
1580 KX = 0x0024,
1581 CERT = 0x0025,
1582 A6 = 0x0026,
1583 DNAME = 0x0027,
1584 SINK = 0x0028,
1585 OPT = 0x0029,
1586 DS = 0x002B,
1587 RRSIG = 0x002E,
1588 NSEC = 0x002F,
1589 DNSKEY = 0x0030,
1590 DHCID = 0x0031,
1591 UINFO = 0x0064,
1592 UID = 0x0065,
1593 GID = 0x0066,
1594 UNSPEC = 0x0067,
1595 ADDRS = 0x00f8,
1596 TKEY = 0x00f9,
1597 TSIG = 0x00fa,
1598 IXFR = 0x00fb,
1599 AXFR = 0x00fc,
1600 MAILB = 0x00fd,
1601 MAILA = 0x00fe,
1602 ALL = 0x00ff,
1603 WINS = 0xff01,
1604 WINSR = 0xff02,
1605 TLSA = 0x0034,
1606 SVCB = 0x0040,
1607 HTTPS = 0x0041,
1608 pub const NBSTAT: TYPE = .WINSR;
1609 pub const ANY: TYPE = .ALL;
1610 };
1611
1612 pub const QUERY = packed struct(ULONG64) {
1613 pub const STANDARD: QUERY = .{};
1614 ACCEPT_TRUNCATED_RESPONSE: bool = false,
1615 USE_TCP_ONLY: bool = false,
1616 NO_RECURSION: bool = false,
1617 BYPASS_CACHE: bool = false,
1618 NO_WIRE_QUERY: bool = false,
1619 NO_LOCAL_NAME: bool = false,
1620 NO_HOSTS_FILE: bool = false,
1621 NO_NETBT: bool = false,
1622 WIRE_ONLY: bool = false,
1623 RETURN_MESSAGE: bool = false,
1624 MULTICAST_ONLY: bool = false,
1625 NO_MULTICAST: bool = false,
1626 TREAT_AS_FQDN: bool = false,
1627 ADDRCONFIG: bool = false,
1628 DUAL_ADDR: bool = false,
1629 Reserved15: u2 = 0,
1630 MULTICAST_WAIT: bool = false,
1631 MULTICAST_VERIFY: bool = false,
1632 Reserved19: u1 = 0,
1633 DONT_RESET_TTL_VALUES: bool = false,
1634 DISABLE_IDN_ENCODING: bool = false,
1635 Reserved22: u1 = 0,
1636 APPEND_MULTILABEL: bool = false,
1637 Reserved24: u34 = 0,
1638 PARSE_ALL_RECORDS: bool = false,
1639 Reserved59: u5 = 0,
1640
1641 pub const REQUEST = extern struct {
1642 Version: DWORD,
1643 QueryName: PCWSTR,
1644 QueryType: TYPE,
1645 QueryOptions: QUERY = .STANDARD,
1646 pDnsServerList: ?*ADDR.ARRAY = null,
1647 InterfaceIndex: ULONG = 0,
1648 pQueryCompletionCallback: ?*const COMPLETION_ROUTINE = null,
1649 pQueryContext: ?*anyopaque = null,
1650
1651 pub const @"3" = extern struct {
1652 Base: REQUEST,
1653 IsNetworkQueryRequired: BOOL = .FALSE,
1654 RequiredNetworkIndex: DWORD = 0,
1655 cCustomServers: DWORD = 0,
1656 pCustomServers: ?*CUSTOM_SERVER = null,
1657 };
1658 };
1659 pub const RESULT = extern struct {
1660 Version: ULONG,
1661 QueryStatus: STATUS,
1662 QueryOptions: QUERY,
1663 pQueryRecords: ?*RECORD,
1664 Reserved: ?*anyopaque,
1665 };
1666 pub const CANCEL = extern struct {
1667 Reserved: [32]CHAR align(8),
1668 };
1669 pub const COMPLETION_ROUTINE = fn (
1670 pQueryContext: ?*anyopaque,
1671 pQueryResults: *RESULT,
1672 ) callconv(.winapi) void;
1673 };
1674 pub const FREE_TYPE = enum(c_int) { Flat = 0, RecordList, ParsedMessageFields };
1675 pub const RECORD = extern struct {
1676 pNext: ?*RECORD,
1677 pName: *anyopaque,
1678 wType: TYPE,
1679 wDataLength: WORD,
1680 Flags: FLAGS,
1681 dwTtl: DWORD,
1682 dwReserved: DWORD,
1683 Data: extern union { A: [4]u8, AAAA: [16]u8 },
1684
1685 pub const FLAGS = packed struct(DWORD) {
1686 Section: SECTION,
1687 Delete: u1,
1688 CharSet: u2,
1689 Unused: u3,
1690 Reserved: u24,
1691 };
1692 };
1693 pub const SECTION = enum(u2) { Question, Answer, Authority, Additional };
1694};
1695
1696// ref: km/ntddk.h
1697
1698pub const SYSTEM = struct {
1699 pub const INFORMATION_CLASS = enum(c_int) {
1700 Basic = 0,
1701 Performance = 2,
1702 TimeOfDay = 3,
1703 Process = 5,
1704 ProcessorPerformance = 8,
1705 Interrupt = 23,
1706 Exception = 33,
1707 RegistryQuota = 37,
1708 Lookaside = 45,
1709 CodeIntegrity = 103,
1710 Policy = 134,
1711 _,
1712 };
1713
1714 pub const BASIC_INFORMATION = extern struct {
1715 Reserved: ULONG,
1716 TimerResolution: ULONG,
1717 PageSize: ULONG,
1718 NumberOfPhysicalPages: ULONG,
1719 LowestPhysicalPageNumber: ULONG,
1720 HighestPhysicalPageNumber: ULONG,
1721 AllocationGranularity: ULONG,
1722 MinimumUserModeAddress: ULONG_PTR,
1723 MaximumUserModeAddress: ULONG_PTR,
1724 ActiveProcessorsAffinityMask: KAFFINITY,
1725 NumberOfProcessors: UCHAR,
1726 };
1727};
1728
1729pub const PROCESS = struct {
1730 pub const INFORMATION = extern struct {
1731 hProcess: HANDLE,
1732 hThread: HANDLE,
1733 dwProcessId: DWORD,
1734 dwThreadId: DWORD,
1735 };
1736
1737 pub const INFOCLASS = enum(c_int) {
1738 BasicInformation = 0,
1739 QuotaLimits = 1,
1740 IoCounters = 2,
1741 VmCounters = 3,
1742 Times = 4,
1743 BasePriority = 5,
1744 RaisePriority = 6,
1745 DebugPort = 7,
1746 ExceptionPort = 8,
1747 AccessToken = 9,
1748 LdtInformation = 10,
1749 LdtSize = 11,
1750 DefaultHardErrorMode = 12,
1751 IoPortHandlers = 13,
1752 PooledUsageAndLimits = 14,
1753 WorkingSetWatch = 15,
1754 UserModeIOPL = 16,
1755 EnableAlignmentFaultFixup = 17,
1756 PriorityClass = 18,
1757 Wx86Information = 19,
1758 HandleCount = 20,
1759 AffinityMask = 21,
1760 PriorityBoost = 22,
1761 DeviceMap = 23,
1762 SessionInformation = 24,
1763 ForegroundInformation = 25,
1764 Wow64Information = 26,
1765 ImageFileName = 27,
1766 LUIDDeviceMapsEnabled = 28,
1767 BreakOnTermination = 29,
1768 DebugObjectHandle = 30,
1769 DebugFlags = 31,
1770 HandleTracing = 32,
1771 IoPriority = 33,
1772 ExecuteFlags = 34,
1773 TlsInformation = 35,
1774 Cookie = 36,
1775 ImageInformation = 37,
1776 CycleTime = 38,
1777 PagePriority = 39,
1778 InstrumentationCallback = 40,
1779 ThreadStackAllocation = 41,
1780 WorkingSetWatchEx = 42,
1781 ImageFileNameWin32 = 43,
1782 ImageFileMapping = 44,
1783 AffinityUpdateMode = 45,
1784 MemoryAllocationMode = 46,
1785 GroupInformation = 47,
1786 TokenVirtualizationEnabled = 48,
1787 OwnerInformation = 49,
1788 WindowInformation = 50,
1789 HandleInformation = 51,
1790 MitigationPolicy = 52,
1791 DynamicFunctionTableInformation = 53,
1792 HandleCheckingMode = 54,
1793 KeepAliveCount = 55,
1794 RevokeFileHandles = 56,
1795 WorkingSetControl = 57,
1796 HandleTable = 58,
1797 CheckStackExtentsMode = 59,
1798 CommandLineInformation = 60,
1799 ProtectionInformation = 61,
1800 MemoryExhaustion = 62,
1801 FaultInformation = 63,
1802 TelemetryIdInformation = 64,
1803 CommitReleaseInformation = 65,
1804 Reserved1Information = 66,
1805 Reserved2Information = 67,
1806 SubsystemProcess = 68,
1807 InPrivate = 70,
1808 RaiseUMExceptionOnInvalidHandleClose = 71,
1809 SubsystemInformation = 75,
1810 Win32kSyscallFilterInformation = 79,
1811 EnergyTrackingState = 82,
1812 NetworkIoCounters = 114,
1813 _,
1814
1815 pub const Max: @typeInfo(@This()).@"enum".tag_type = 117;
1816 };
1817
1818 pub const BASIC_INFORMATION = extern struct {
1819 ExitStatus: NTSTATUS,
1820 PebBaseAddress: *PEB,
1821 AffinityMask: ULONG_PTR,
1822 BasePriority: KPRIORITY,
1823 UniqueProcessId: ULONG_PTR,
1824 InheritedFromUniqueProcessId: ULONG_PTR,
1825 };
1826
1827 pub const VM_COUNTERS = extern struct {
1828 PeakVirtualSize: SIZE_T,
1829 VirtualSize: SIZE_T,
1830 PageFaultCount: ULONG,
1831 PeakWorkingSetSize: SIZE_T,
1832 WorkingSetSize: SIZE_T,
1833 QuotaPeakPagedPoolUsage: SIZE_T,
1834 QuotaPagedPoolUsage: SIZE_T,
1835 QuotaPeakNonPagedPoolUsage: SIZE_T,
1836 QuotaNonPagedPoolUsage: SIZE_T,
1837 PagefileUsage: SIZE_T,
1838 PeakPagefileUsage: SIZE_T,
1839 };
1840};
1841
1842pub const THREAD = struct {
1843 pub const INFOCLASS = enum(c_int) {
1844 BasicInformation = 0,
1845 Times = 1,
1846 Priority = 2,
1847 BasePriority = 3,
1848 AffinityMask = 4,
1849 ImpersonationToken = 5,
1850 DescriptorTableEntry = 6,
1851 EnableAlignmentFaultFixup = 7,
1852 EventPair_Reusable = 8,
1853 QuerySetWin32StartAddress = 9,
1854 ZeroTlsCell = 10,
1855 PerformanceCount = 11,
1856 AmILastThread = 12,
1857 IdealProcessor = 13,
1858 PriorityBoost = 14,
1859 SetTlsArrayAddress = 15,
1860 IsIoPending = 16,
1861 // Windows 2000+ from here
1862 HideFromDebugger = 17,
1863 // Windows XP+ from here
1864 BreakOnTermination = 18,
1865 SwitchLegacyState = 19,
1866 IsTerminated = 20,
1867 // Windows Vista+ from here
1868 LastSystemCall = 21,
1869 IoPriority = 22,
1870 CycleTime = 23,
1871 PagePriority = 24,
1872 ActualBasePriority = 25,
1873 TebInformation = 26,
1874 CSwitchMon = 27,
1875 // Windows 7+ from here
1876 CSwitchPmu = 28,
1877 Wow64Context = 29,
1878 GroupInformation = 30,
1879 UmsInformation = 31,
1880 CounterProfiling = 32,
1881 IdealProcessorEx = 33,
1882 // Windows 8+ from here
1883 CpuAccountingInformation = 34,
1884 // Windows 8.1+ from here
1885 SuspendCount = 35,
1886 // Windows 10+ from here
1887 HeterogeneousCpuPolicy = 36,
1888 ContainerId = 37,
1889 NameInformation = 38,
1890 SelectedCpuSets = 39,
1891 SystemThreadInformation = 40,
1892 ActualGroupAffinity = 41,
1893 DynamicCodePolicyInfo = 42,
1894 SubsystemInformation = 45,
1895 _,
1896
1897 pub const Max: @typeInfo(@This()).@"enum".tag_type = 60;
1898 };
1899
1900 pub const BASIC_INFORMATION = extern struct {
1901 ExitStatus: NTSTATUS,
1902 TebBaseAddress: PVOID,
1903 ClientId: CLIENT_ID,
1904 AffinityMask: KAFFINITY,
1905 Priority: KPRIORITY,
1906 BasePriority: KPRIORITY,
1907 };
1908
1909 pub const CREATE_FLAGS = packed struct(ULONG) {
1910 CREATE_SUSPENDED: bool = false,
1911 SKIP_THREAD_ATTACH: bool = false,
1912 HIDE_FROM_DEBUGGER: bool = false,
1913 LOADER_WORKER: bool = false,
1914 SKIP_LOADER_INIT: bool = false,
1915 BYPASS_PROCESS_FREEZE: bool = false,
1916 Reserved6: u26 = 0,
1917
1918 pub const NONE: CREATE_FLAGS = .{};
1919 };
1920
1921 pub const StackSize = enum(SIZE_T) {
1922 /// The default size specified in the executable header
1923 default = 0,
1924 _,
1925 };
1926};
1927
1928// ref: km/ntifs.h
1929
1930pub const HEAP = opaque {
1931 pub const FLAGS = packed struct(u8) {
1932 /// Serialized access is not used when the heap functions access this heap. This option
1933 /// applies to all subsequent heap function calls. Alternatively, you can specify this
1934 /// option on individual heap function calls.
1935 ///
1936 /// The low-fragmentation heap (LFH) cannot be enabled for a heap created with this option.
1937 ///
1938 /// A heap created with this option cannot be locked.
1939 NO_SERIALIZE: bool = false,
1940 /// Specifies that the heap is growable. Must be specified if `HeapBase` is `NULL`.
1941 GROWABLE: bool = false,
1942 /// The system raises an exception to indicate failure (for example, an out-of-memory
1943 /// condition) for calls to `HeapAlloc` and `HeapReAlloc` instead of returning `NULL`.
1944 ///
1945 /// To ensure that exceptions are generated for all calls to an allocation function, specify
1946 /// `GENERATE_EXCEPTIONS` in the call to `HeapCreate`. In this case, it is not necessary to
1947 /// additionally specify `GENERATE_EXCEPTIONS` in the allocation function calls.
1948 GENERATE_EXCEPTIONS: bool = false,
1949 /// The allocated memory will be initialized to zero. Otherwise, the memory is not
1950 /// initialized to zero.
1951 ZERO_MEMORY: bool = false,
1952 REALLOC_IN_PLACE_ONLY: bool = false,
1953 TAIL_CHECKING_ENABLED: bool = false,
1954 FREE_CHECKING_ENABLED: bool = false,
1955 DISABLE_COALESCE_ON_FREE: bool = false,
1956
1957 pub const CLASS = enum(u4) {
1958 /// process heap
1959 PROCESS,
1960 /// private heap
1961 PRIVATE,
1962 /// Kernel Heap
1963 KERNEL,
1964 /// GDI heap
1965 GDI,
1966 /// User heap
1967 USER,
1968 /// Console heap
1969 CONSOLE,
1970 /// User Desktop heap
1971 USER_DESKTOP,
1972 /// Csrss Shared heap
1973 CSRSS_SHARED,
1974 /// Csr Port heap
1975 CSR_PORT,
1976 _,
1977
1978 pub const MASK: CLASS = @fromBackingInt(@intCast(maxInt(@typeInfo(CLASS).@"enum".tag_type)));
1979 };
1980
1981 pub const CREATE = packed struct(ULONG) {
1982 COMMON: FLAGS = .{},
1983 SEGMENT_HEAP: bool = false,
1984 /// Only applies to segment heap. Applies pointer obfuscation which is
1985 /// generally excessive and unnecessary but is necessary for certain insecure
1986 /// heaps in win32k.
1987 ///
1988 /// Specifying HEAP_CREATE_HARDENED prevents the heap from using locks as
1989 /// pointers would potentially be exposed in heap metadata lock variables.
1990 /// Callers are therefore responsible for synchronizing access to hardened heaps.
1991 HARDENED: bool = false,
1992 Reserved10: u2 = 0,
1993 CLASS: CLASS = @fromBackingInt(@intCast(0)),
1994 /// Create heap with 16 byte alignment (obsolete)
1995 ALIGN_16: bool = false,
1996 /// Create heap call tracing enabled (obsolete)
1997 ENABLE_TRACING: bool = false,
1998 /// Create heap with executable pages
1999 ///
2000 /// All memory blocks that are allocated from this heap allow code execution, if the
2001 /// hardware enforces data execution prevention. Use this flag heap in applications that
2002 /// run code from the heap. If `ENABLE_EXECUTE` is not specified and an application
2003 /// attempts to run code from a protected page, the application receives an exception
2004 /// with the status code `STATUS_ACCESS_VIOLATION`.
2005 ENABLE_EXECUTE: bool = false,
2006 Reserved19: u13 = 0,
2007
2008 pub const VALID_MASK: CREATE = .{
2009 .COMMON = .{
2010 .NO_SERIALIZE = true,
2011 .GROWABLE = true,
2012 .GENERATE_EXCEPTIONS = true,
2013 .ZERO_MEMORY = true,
2014 .REALLOC_IN_PLACE_ONLY = true,
2015 .TAIL_CHECKING_ENABLED = true,
2016 .FREE_CHECKING_ENABLED = true,
2017 .DISABLE_COALESCE_ON_FREE = true,
2018 },
2019 .CLASS = .MASK,
2020 .ALIGN_16 = true,
2021 .ENABLE_TRACING = true,
2022 .ENABLE_EXECUTE = true,
2023 .SEGMENT_HEAP = true,
2024 .HARDENED = true,
2025 };
2026 };
2027
2028 pub const ALLOCATION = packed struct(ULONG) {
2029 COMMON: FLAGS = .{},
2030 SETTABLE_USER: packed struct(u4) {
2031 VALUE: u1 = 0,
2032 FLAGS: packed struct(u3) {
2033 FLAG1: bool = false,
2034 FLAG2: bool = false,
2035 FLAG3: bool = false,
2036 } = .{},
2037 } = .{},
2038 CLASS: CLASS = @fromBackingInt(@intCast(0)),
2039 Reserved16: u2 = 0,
2040 TAG: u12 = 0,
2041 Reserved30: u2 = 0,
2042 };
2043 };
2044
2045 pub const RTL_PARAMETERS = extern struct {
2046 Length: ULONG,
2047 SegmentReserve: SIZE_T,
2048 SegmentCommit: SIZE_T,
2049 DeCommitFreeBlockThreshold: SIZE_T,
2050 DeCommitTotalFreeThreshold: SIZE_T,
2051 MaximumAllocationSize: SIZE_T,
2052 VirtualMemoryThreshold: SIZE_T,
2053 InitialCommit: SIZE_T,
2054 InitialReserve: SIZE_T,
2055 CommitRoutine: *const COMMIT_ROUTINE,
2056 Reserved: [2]SIZE_T = @splat(0),
2057
2058 pub const COMMIT_ROUTINE = fn (
2059 Base: PVOID,
2060 CommitAddress: *PVOID,
2061 CommitSize: *SIZE_T,
2062 ) callconv(.winapi) NTSTATUS;
2063
2064 pub const SEGMENT = extern struct {
2065 Version: VERSION,
2066 Size: USHORT,
2067 Flags: FLG,
2068 MemorySource: MEMORY_SOURCE,
2069 Reserved: [4]SIZE_T,
2070
2071 pub const VERSION = enum(USHORT) {
2072 CURRENT = 3,
2073 _,
2074 };
2075
2076 pub const FLG = packed struct(ULONG) {
2077 USE_PAGE_HEAP: bool = false,
2078 NO_LFH: bool = false,
2079 Reserved2: u30 = 0,
2080
2081 pub const VALID_FLAGS: FLG = .{
2082 .USE_PAGE_HEAP = true,
2083 .NO_LFH = true,
2084 };
2085 };
2086
2087 pub const MEMORY_SOURCE = extern struct {
2088 Flags: ULONG,
2089 MemoryTypeMask: TYPE,
2090 NumaNode: ULONG,
2091 u: extern union {
2092 PartitionHandle: HANDLE,
2093 Callbacks: *const VA_CALLBACKS,
2094 },
2095 Reserved: [2]SIZE_T = @splat(0),
2096
2097 pub const TYPE = enum(ULONG) {
2098 Paged,
2099 NonPaged,
2100 @"64KPage",
2101 LargePage,
2102 HugePage,
2103 Custom,
2104 _,
2105
2106 pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".field_names.len;
2107 };
2108
2109 pub const VA_CALLBACKS = extern struct {
2110 CallbackContext: HANDLE,
2111 AllocateVirtualMemory: *const ALLOCATE_VIRTUAL_MEMORY_EX_CALLBACK,
2112 FreeVirtualMemory: *const FREE_VIRTUAL_MEMORY_EX_CALLBACK,
2113 QueryVirtualMemory: *const QUERY_VIRTUAL_MEMORY_CALLBACK,
2114
2115 pub const ALLOCATE_VIRTUAL_MEMORY_EX_CALLBACK = fn (
2116 CallbackContext: HANDLE,
2117 BaseAddress: *PVOID,
2118 RegionSize: *SIZE_T,
2119 AllocationType: ULONG,
2120 PageProtection: ULONG,
2121 ExtendedParameters: ?[*]MEM.EXTENDED_PARAMETER,
2122 ExtendedParameterCount: ULONG,
2123 ) callconv(.c) NTSTATUS;
2124
2125 pub const FREE_VIRTUAL_MEMORY_EX_CALLBACK = fn (
2126 CallbackContext: HANDLE,
2127 ProcessHandle: HANDLE,
2128 BaseAddress: *PVOID,
2129 RegionSize: *SIZE_T,
2130 FreeType: ULONG,
2131 ) callconv(.c) NTSTATUS;
2132
2133 pub const QUERY_VIRTUAL_MEMORY_CALLBACK = fn (
2134 CallbackContext: HANDLE,
2135 ProcessHandle: HANDLE,
2136 BaseAddress: *PVOID,
2137 MemoryInformationClass: MEMORY_INFO_CLASS,
2138 MemoryInformation: PVOID,
2139 MemoryInformationLength: SIZE_T,
2140 ReturnLength: ?*SIZE_T,
2141 ) callconv(.c) NTSTATUS;
2142
2143 pub const MEMORY_INFO_CLASS = enum(c_int) {
2144 Basic,
2145 _,
2146 };
2147 };
2148 };
2149 };
2150 };
2151};
2152
2153pub const CTL_CODE = packed struct(ULONG) {
2154 Method: METHOD,
2155 Function: u12,
2156 Access: FILE_ACCESS,
2157 DeviceType: FILE_DEVICE,
2158
2159 pub const METHOD = enum(u2) {
2160 BUFFERED = 0,
2161 IN_DIRECT = 1,
2162 OUT_DIRECT = 2,
2163 NEITHER = 3,
2164 };
2165
2166 pub const FILE_ACCESS = packed struct(u2) {
2167 READ: bool = false,
2168 WRITE: bool = false,
2169
2170 pub const ANY: FILE_ACCESS = .{ .READ = false, .WRITE = false };
2171 pub const SPECIAL = ANY;
2172 };
2173
2174 pub const FILE_DEVICE = enum(u16) {
2175 BEEP = 0x00000001,
2176 CD_ROM = 0x00000002,
2177 CD_ROM_FILE_SYSTEM = 0x00000003,
2178 CONTROLLER = 0x00000004,
2179 DATALINK = 0x00000005,
2180 DFS = 0x00000006,
2181 DISK = 0x00000007,
2182 DISK_FILE_SYSTEM = 0x00000008,
2183 FILE_SYSTEM = 0x00000009,
2184 INPORT_PORT = 0x0000000a,
2185 KEYBOARD = 0x0000000b,
2186 MAILSLOT = 0x0000000c,
2187 MIDI_IN = 0x0000000d,
2188 MIDI_OUT = 0x0000000e,
2189 MOUSE = 0x0000000f,
2190 MULTI_UNC_PROVIDER = 0x00000010,
2191 NAMED_PIPE = 0x00000011,
2192 NETWORK = 0x00000012,
2193 NETWORK_BROWSER = 0x00000013,
2194 NETWORK_FILE_SYSTEM = 0x00000014,
2195 NULL = 0x00000015,
2196 PARALLEL_PORT = 0x00000016,
2197 PHYSICAL_NETCARD = 0x00000017,
2198 PRINTER = 0x00000018,
2199 SCANNER = 0x00000019,
2200 SERIAL_MOUSE_PORT = 0x0000001a,
2201 SERIAL_PORT = 0x0000001b,
2202 SCREEN = 0x0000001c,
2203 SOUND = 0x0000001d,
2204 STREAMS = 0x0000001e,
2205 TAPE = 0x0000001f,
2206 TAPE_FILE_SYSTEM = 0x00000020,
2207 TRANSPORT = 0x00000021,
2208 UNKNOWN = 0x00000022,
2209 VIDEO = 0x00000023,
2210 VIRTUAL_DISK = 0x00000024,
2211 WAVE_IN = 0x00000025,
2212 WAVE_OUT = 0x00000026,
2213 @"8042_PORT" = 0x00000027,
2214 NETWORK_REDIRECTOR = 0x00000028,
2215 BATTERY = 0x00000029,
2216 BUS_EXTENDER = 0x0000002a,
2217 MODEM = 0x0000002b,
2218 VDM = 0x0000002c,
2219 MASS_STORAGE = 0x0000002d,
2220 SMB = 0x0000002e,
2221 KS = 0x0000002f,
2222 CHANGER = 0x00000030,
2223 SMARTCARD = 0x00000031,
2224 ACPI = 0x00000032,
2225 DVD = 0x00000033,
2226 FULLSCREEN_VIDEO = 0x00000034,
2227 DFS_FILE_SYSTEM = 0x00000035,
2228 DFS_VOLUME = 0x00000036,
2229 SERENUM = 0x00000037,
2230 TERMSRV = 0x00000038,
2231 KSEC = 0x00000039,
2232 FIPS = 0x0000003A,
2233 INFINIBAND = 0x0000003B,
2234 VMBUS = 0x0000003E,
2235 CRYPT_PROVIDER = 0x0000003F,
2236 WPD = 0x00000040,
2237 BLUETOOTH = 0x00000041,
2238 MT_COMPOSITE = 0x00000042,
2239 MT_TRANSPORT = 0x00000043,
2240 BIOMETRIC = 0x00000044,
2241 PMI = 0x00000045,
2242 EHSTOR = 0x00000046,
2243 DEVAPI = 0x00000047,
2244 GPIO = 0x00000048,
2245 USBEX = 0x00000049,
2246 CONSOLE = 0x00000050,
2247 NFP = 0x00000051,
2248 SYSENV = 0x00000052,
2249 VIRTUAL_BLOCK = 0x00000053,
2250 POINT_OF_SERVICE = 0x00000054,
2251 STORAGE_REPLICATION = 0x00000055,
2252 TRUST_ENV = 0x00000056,
2253 UCM = 0x00000057,
2254 UCMTCPCI = 0x00000058,
2255 PERSISTENT_MEMORY = 0x00000059,
2256 NVDIMM = 0x0000005a,
2257 HOLOGRAPHIC = 0x0000005b,
2258 SDFXHCI = 0x0000005c,
2259 UCMUCSI = 0x0000005d,
2260 PRM = 0x0000005e,
2261 EVENT_COLLECTOR = 0x0000005f,
2262 USB4 = 0x00000060,
2263 SOUNDWIRE = 0x00000061,
2264
2265 MOUNTMGRCONTROLTYPE = 'm',
2266
2267 _,
2268 };
2269
2270 pub const SET_REPARSE_POINT: CTL_CODE = .{ .DeviceType = .FILE_SYSTEM, .Function = 41, .Method = .BUFFERED, .Access = .SPECIAL };
2271 pub const GET_REPARSE_POINT: CTL_CODE = .{ .DeviceType = .FILE_SYSTEM, .Function = 42, .Method = .BUFFERED, .Access = .ANY };
2272
2273 pub const PIPE = struct {
2274 pub const ASSIGN_EVENT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 0, .Method = .BUFFERED, .Access = .ANY };
2275 pub const DISCONNECT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 1, .Method = .BUFFERED, .Access = .ANY };
2276 pub const LISTEN: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2, .Method = .BUFFERED, .Access = .ANY };
2277 pub const PEEK: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 3, .Method = .BUFFERED, .Access = .{ .READ = true } };
2278 pub const QUERY_EVENT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 4, .Method = .BUFFERED, .Access = .ANY };
2279 pub const TRANSCEIVE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 5, .Method = .NEITHER, .Access = .{ .READ = true, .WRITE = true } };
2280 pub const WAIT: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 6, .Method = .BUFFERED, .Access = .ANY };
2281 pub const IMPERSONATE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 7, .Method = .BUFFERED, .Access = .ANY };
2282 pub const SET_CLIENT_PROCESS: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 8, .Method = .BUFFERED, .Access = .ANY };
2283 pub const QUERY_CLIENT_PROCESS: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 9, .Method = .BUFFERED, .Access = .ANY };
2284 pub const GET_PIPE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 10, .Method = .BUFFERED, .Access = .ANY };
2285 pub const SET_PIPE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 11, .Method = .BUFFERED, .Access = .ANY };
2286 pub const GET_CONNECTION_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 12, .Method = .BUFFERED, .Access = .ANY };
2287 pub const SET_CONNECTION_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 13, .Method = .BUFFERED, .Access = .ANY };
2288 pub const GET_HANDLE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 14, .Method = .BUFFERED, .Access = .ANY };
2289 pub const SET_HANDLE_ATTRIBUTE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 15, .Method = .BUFFERED, .Access = .ANY };
2290 pub const FLUSH: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 16, .Method = .BUFFERED, .Access = .{ .WRITE = true } };
2291
2292 pub const INTERNAL_READ: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2045, .Method = .BUFFERED, .Access = .{ .READ = true } };
2293 pub const INTERNAL_WRITE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2046, .Method = .BUFFERED, .Access = .{ .WRITE = true } };
2294 pub const INTERNAL_TRANSCEIVE: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2047, .Method = .NEITHER, .Access = .{ .READ = true, .WRITE = true } };
2295 pub const INTERNAL_READ_OVFLOW: CTL_CODE = .{ .DeviceType = .NAMED_PIPE, .Function = 2048, .Method = .BUFFERED, .Access = .{ .READ = true } };
2296 };
2297};
2298
2299pub const IOCTL = struct {
2300 pub const AFD = struct {
2301 const CONTROL_CODE = packed struct {
2302 Method: CTL_CODE.METHOD,
2303 Function: u10,
2304 DeviceType: CTL_CODE.FILE_DEVICE,
2305 Reserved28: u4 = 0,
2306 };
2307 pub const BIND: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 0, .Method = .NEITHER });
2308 pub const CONNECT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 1, .Method = .NEITHER });
2309 pub const START_LISTEN: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 2, .Method = .NEITHER });
2310 pub const WAIT_FOR_LISTEN: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 3, .Method = .BUFFERED });
2311 pub const ACCEPT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 4, .Method = .BUFFERED });
2312 pub const RECEIVE: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 5, .Method = .NEITHER });
2313 pub const RECEIVE_DATAGRAM: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 6, .Method = .NEITHER });
2314 pub const SEND: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 7, .Method = .NEITHER });
2315 pub const SEND_DATAGRAM: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 8, .Method = .NEITHER });
2316 pub const POLL: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 9, .Method = .BUFFERED });
2317 pub const PARTIAL_DISCONNECT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 10, .Method = .NEITHER });
2318
2319 pub const GET_ADDRESS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 11, .Method = .NEITHER });
2320 pub const QUERY_RECEIVE_INFO: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 12, .Method = .NEITHER });
2321 pub const QUERY_HANDLES: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 13, .Method = .NEITHER });
2322 pub const SET_INFORMATION: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 14, .Method = .NEITHER });
2323 pub const GET_CONTEXT_LENGTH: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 15, .Method = .NEITHER });
2324 pub const GET_CONTEXT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 16, .Method = .NEITHER });
2325 pub const SET_CONTEXT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 17, .Method = .NEITHER });
2326
2327 pub const SET_CONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 18, .Method = .BUFFERED });
2328 pub const SET_CONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 19, .Method = .BUFFERED });
2329 pub const SET_DISCONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 20, .Method = .BUFFERED });
2330 pub const SET_DISCONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 21, .Method = .BUFFERED });
2331 pub const GET_CONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 22, .Method = .BUFFERED });
2332 pub const GET_CONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 23, .Method = .BUFFERED });
2333 pub const GET_DISCONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 24, .Method = .BUFFERED });
2334 pub const GET_DISCONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 25, .Method = .BUFFERED });
2335 pub const SIZE_CONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 26, .Method = .BUFFERED });
2336 pub const SIZE_CONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 27, .Method = .BUFFERED });
2337 pub const SIZE_DISCONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 28, .Method = .BUFFERED });
2338 pub const SIZE_DISCONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 29, .Method = .BUFFERED });
2339
2340 pub const GET_INFORMATION: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 30, .Method = .NEITHER });
2341 pub const TRANSMIT_FILE: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 31, .Method = .NEITHER });
2342 pub const SUPER_ACCEPT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 32, .Method = .NEITHER });
2343
2344 pub const EVENT_SELECT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 33, .Method = .BUFFERED });
2345 pub const ENUM_NETWORK_EVENTS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 34, .Method = .BUFFERED });
2346
2347 pub const DEFER_ACCEPT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 35, .Method = .BUFFERED });
2348 pub const WAIT_FOR_LISTEN_LIFO: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 36, .Method = .BUFFERED });
2349 pub const SET_QOS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 37, .Method = .BUFFERED });
2350 pub const GET_QOS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 38, .Method = .BUFFERED });
2351 pub const NO_OPERATION: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 39, .Method = .NEITHER });
2352 pub const VALIDATE_GROUP: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 40, .Method = .BUFFERED });
2353 pub const GET_UNACCEPTED_CONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 41, .Method = .BUFFERED });
2354
2355 pub const QUEUE_APC: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 42, .Method = .BUFFERED });
2356
2357 pub const SOCKOPT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 47, .Method = .NEITHER });
2358 pub const SUPER_CONNECT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 49, .Method = .NEITHER });
2359 pub const RECV_MSG: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 51, .Method = .NEITHER });
2360 pub const RIO: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 70, .Method = .NEITHER });
2361 };
2362 pub const CONDRV = struct {
2363 pub const READ_IO: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 1, .Method = .OUT_DIRECT, .Access = .ANY };
2364 pub const COMPLETE_IO: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 2, .Method = .NEITHER, .Access = .ANY };
2365 pub const READ_INPUT: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 3, .Method = .NEITHER, .Access = .ANY };
2366 pub const WRITE_OUTPUT: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 4, .Method = .NEITHER, .Access = .ANY };
2367 pub const ISSUE_USER_IO: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 5, .Method = .OUT_DIRECT, .Access = .ANY };
2368 pub const DISCONNECT_PIPE: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 6, .Method = .NEITHER, .Access = .ANY };
2369 pub const SET_SERVER_INFORMATION: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 7, .Method = .NEITHER, .Access = .ANY };
2370 pub const GET_SERVER_PID: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 8, .Method = .NEITHER, .Access = .ANY };
2371 pub const GET_DISPLAY_SIZE: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 9, .Method = .NEITHER, .Access = .ANY };
2372 pub const UPDATE_DISPLAY: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 10, .Method = .NEITHER, .Access = .ANY };
2373 pub const SET_CURSOR: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 11, .Method = .NEITHER, .Access = .ANY };
2374 pub const ALLOW_VIA_UIACCESS: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 12, .Method = .NEITHER, .Access = .ANY };
2375 pub const LAUNCH_SERVER: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 13, .Method = .NEITHER, .Access = .ANY };
2376 pub const GET_FONT_SIZE: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 14, .Method = .NEITHER, .Access = .ANY };
2377 };
2378 pub const KSEC = struct {
2379 pub const GEN_RANDOM: CTL_CODE = .{ .DeviceType = .KSEC, .Function = 2, .Method = .BUFFERED, .Access = .ANY };
2380 };
2381 pub const MOUNTMGR = struct {
2382 pub const QUERY_POINTS: CTL_CODE = .{ .DeviceType = .MOUNTMGRCONTROLTYPE, .Function = 2, .Method = .BUFFERED, .Access = .ANY };
2383 pub const QUERY_DOS_VOLUME_PATH: CTL_CODE = .{ .DeviceType = .MOUNTMGRCONTROLTYPE, .Function = 12, .Method = .BUFFERED, .Access = .ANY };
2384 };
2385};
2386
2387pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: ULONG = 16 * 1024;
2388
2389pub const IO_REPARSE_TAG = packed struct(ULONG) {
2390 Value: u12,
2391 Index: u4 = 0,
2392 ReservedBits: u12 = 0,
2393 /// Can have children if a directory.
2394 IsDirectory: bool = false,
2395 /// Represents another named entity in the system.
2396 IsSurrogate: bool = false,
2397 /// Must be `false` for non-Microsoft tags.
2398 IsReserved: bool = false,
2399 /// Owned by Microsoft.
2400 IsMicrosoft: bool = false,
2401
2402 pub const RESERVED_INVALID: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsReserved = true, .Index = 0x8, .Value = 0x000 };
2403 pub const MOUNT_POINT: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x003 };
2404 pub const HSM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsReserved = true, .Value = 0x004 };
2405 pub const DRIVE_EXTENDER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x005 };
2406 pub const HSM2: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x006 };
2407 pub const SIS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x007 };
2408 pub const WIM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x008 };
2409 pub const CSV: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x009 };
2410 pub const DFS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x00A };
2411 pub const FILTER_MANAGER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x00B };
2412 pub const SYMLINK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x00C };
2413 pub const IIS_CACHE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x010 };
2414 pub const DFSR: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x012 };
2415 pub const DEDUP: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x013 };
2416 pub const APPXSTRM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsReserved = true, .Value = 0x014 };
2417 pub const NFS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x014 };
2418 pub const FILE_PLACEHOLDER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x015 };
2419 pub const DFM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x016 };
2420 pub const WOF: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x017 };
2421 pub inline fn WCI(index: u1) IO_REPARSE_TAG {
2422 return .{ .IsMicrosoft = true, .IsDirectory = index == 0x1, .Index = index, .Value = 0x018 };
2423 }
2424 pub const GLOBAL_REPARSE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x0019 };
2425 pub inline fn CLOUD(index: u4) IO_REPARSE_TAG {
2426 return .{ .IsMicrosoft = true, .IsDirectory = true, .Index = index, .Value = 0x01A };
2427 }
2428 pub const APPEXECLINK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x01B };
2429 pub const PROJFS: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsDirectory = true, .Value = 0x01C };
2430 pub const LX_SYMLINK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x01D };
2431 pub const STORAGE_SYNC: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x01E };
2432 pub const WCI_TOMBSTONE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x01F };
2433 pub const UNHANDLED: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x020 };
2434 pub const ONEDRIVE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x021 };
2435 pub const PROJFS_TOMBSTONE: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x022 };
2436 pub const AF_UNIX: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x023 };
2437 pub const LX_FIFO: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x024 };
2438 pub const LX_CHR: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x025 };
2439 pub const LX_BLK: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .Value = 0x026 };
2440 pub const LX_STORAGE_SYNC_FOLDER: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsDirectory = true, .Value = 0x027 };
2441 pub inline fn WCI_LINK(index: u1) IO_REPARSE_TAG {
2442 return .{ .IsMicrosoft = true, .IsSurrogate = true, .Index = index, .Value = 0x027 };
2443 }
2444 pub const DATALESS_CIM: IO_REPARSE_TAG = .{ .IsMicrosoft = true, .IsSurrogate = true, .Value = 0x28 };
2445};
2446
2447// ref: km/wdm.h
2448
2449pub const ACCESS_MASK = packed struct(DWORD) {
2450 SPECIFIC: Specific = .{ .bits = 0 },
2451 STANDARD: Standard = .{},
2452 Reserved21: u3 = 0,
2453 ACCESS_SYSTEM_SECURITY: bool = false,
2454 MAXIMUM_ALLOWED: bool = false,
2455 Reserved26: u2 = 0,
2456 GENERIC: Generic = .{},
2457
2458 pub const Specific = packed union {
2459 bits: u16,
2460
2461 // ref: km/wdm.h
2462
2463 /// Define access rights to files and directories
2464 FILE: File,
2465 FILE_DIRECTORY: File.Directory,
2466 FILE_PIPE: File.Pipe,
2467 /// Registry Specific Access Rights.
2468 KEY: Key,
2469 /// Object Manager Object Type Specific Access Rights.
2470 OBJECT_TYPE: ObjectType,
2471 /// Object Manager Directory Specific Access Rights.
2472 DIRECTORY: Directory,
2473 /// Object Manager Symbolic Link Specific Access Rights.
2474 SYMBOLIC_LINK: SymbolicLink,
2475 /// Section Access Rights.
2476 SECTION: Section,
2477 /// Session Specific Access Rights.
2478 SESSION: Session,
2479 /// Process Specific Access Rights.
2480 PROCESS: Process,
2481 /// Thread Specific Access Rights.
2482 THREAD: Thread,
2483 /// Partition Specific Access Rights.
2484 MEMORY_PARTITION: MemoryPartition,
2485 /// Generic mappings for transaction manager rights.
2486 TRANSACTIONMANAGER: TransactionManager,
2487 /// Generic mappings for transaction rights.
2488 TRANSACTION: Transaction,
2489 /// Generic mappings for resource manager rights.
2490 RESOURCEMANAGER: ResourceManager,
2491 /// Generic mappings for enlistment rights.
2492 ENLISTMENT: Enlistment,
2493 /// Event Specific Access Rights.
2494 EVENT: Event,
2495 /// Semaphore Specific Access Rights.
2496 SEMAPHORE: Semaphore,
2497
2498 // ref: km/ntifs.h
2499
2500 /// Token Specific Access Rights.
2501 TOKEN: Token,
2502
2503 // um/winnt.h
2504
2505 /// Job Object Specific Access Rights.
2506 JOB_OBJECT: JobObject,
2507 /// Mutant Specific Access Rights.
2508 MUTANT: Mutant,
2509 /// Timer Specific Access Rights.
2510 TIMER: Timer,
2511 /// I/O Completion Specific Access Rights.
2512 IO_COMPLETION: IoCompletion,
2513
2514 pub const File = packed struct(u16) {
2515 READ_DATA: bool = false,
2516 WRITE_DATA: bool = false,
2517 APPEND_DATA: bool = false,
2518 READ_EA: bool = false,
2519 WRITE_EA: bool = false,
2520 EXECUTE: bool = false,
2521 Reserved6: u1 = 0,
2522 READ_ATTRIBUTES: bool = false,
2523 WRITE_ATTRIBUTES: bool = false,
2524 Reserved9: u7 = 0,
2525
2526 pub const ALL_ACCESS: ACCESS_MASK = .{
2527 .STANDARD = .{
2528 .RIGHTS = .REQUIRED,
2529 .SYNCHRONIZE = true,
2530 },
2531 .SPECIFIC = .{ .FILE = .{
2532 .READ_DATA = true,
2533 .WRITE_DATA = true,
2534 .APPEND_DATA = true,
2535 .READ_EA = true,
2536 .WRITE_EA = true,
2537 .EXECUTE = true,
2538 .Reserved6 = maxInt(@FieldType(File, "Reserved6")),
2539 .READ_ATTRIBUTES = true,
2540 .WRITE_ATTRIBUTES = true,
2541 } },
2542 };
2543
2544 pub const GENERIC_READ: ACCESS_MASK = .{
2545 .STANDARD = .{
2546 .RIGHTS = .READ,
2547 .SYNCHRONIZE = true,
2548 },
2549 .SPECIFIC = .{ .FILE = .{
2550 .READ_DATA = true,
2551 .READ_ATTRIBUTES = true,
2552 .READ_EA = true,
2553 } },
2554 };
2555
2556 pub const GENERIC_WRITE: ACCESS_MASK = .{
2557 .STANDARD = .{
2558 .RIGHTS = .WRITE,
2559 .SYNCHRONIZE = true,
2560 },
2561 .SPECIFIC = .{ .FILE = .{
2562 .WRITE_DATA = true,
2563 .WRITE_ATTRIBUTES = true,
2564 .WRITE_EA = true,
2565 .APPEND_DATA = true,
2566 } },
2567 };
2568
2569 pub const GENERIC_EXECUTE: ACCESS_MASK = .{
2570 .STANDARD = .{
2571 .RIGHTS = .EXECUTE,
2572 .SYNCHRONIZE = true,
2573 },
2574 .SPECIFIC = .{ .FILE = .{
2575 .READ_ATTRIBUTES = true,
2576 .EXECUTE = true,
2577 } },
2578 };
2579
2580 pub const Directory = packed struct(u16) {
2581 LIST: bool = false,
2582 ADD_FILE: bool = false,
2583 ADD_SUBDIRECTORY: bool = false,
2584 READ_EA: bool = false,
2585 WRITE_EA: bool = false,
2586 TRAVERSE: bool = false,
2587 DELETE_CHILD: bool = false,
2588 READ_ATTRIBUTES: bool = false,
2589 WRITE_ATTRIBUTES: bool = false,
2590 Reserved9: u7 = 0,
2591 };
2592
2593 pub const Pipe = packed struct(u16) {
2594 READ_DATA: bool = false,
2595 WRITE_DATA: bool = false,
2596 CREATE_PIPE_INSTANCE: bool = false,
2597 Reserved3: u4 = 0,
2598 READ_ATTRIBUTES: bool = false,
2599 WRITE_ATTRIBUTES: bool = false,
2600 Reserved9: u7 = 0,
2601 };
2602 };
2603
2604 pub const Key = packed struct(u16) {
2605 /// Required to query the values of a registry key.
2606 QUERY_VALUE: bool = false,
2607 /// Required to create, delete, or set a registry value.
2608 SET_VALUE: bool = false,
2609 /// Required to create a subkey of a registry key.
2610 CREATE_SUB_KEY: bool = false,
2611 /// Required to enumerate the subkeys of a registry key.
2612 ENUMERATE_SUB_KEYS: bool = false,
2613 /// Required to request change notifications for a registry key or for subkeys of a registry key.
2614 NOTIFY: bool = false,
2615 /// Reserved for system use.
2616 CREATE_LINK: bool = false,
2617 Reserved6: u2 = 0,
2618 /// Indicates that an application on 64-bit Windows should operate on the 64-bit registry view.
2619 /// This flag is ignored by 32-bit Windows.
2620 WOW64_64KEY: bool = false,
2621 /// Indicates that an application on 64-bit Windows should operate on the 32-bit registry view.
2622 /// This flag is ignored by 32-bit Windows.
2623 WOW64_32KEY: bool = false,
2624 Reserved10: u6 = 0,
2625
2626 pub const WOW64_RES: ACCESS_MASK = .{
2627 .SPECIFIC = .{ .KEY = .{
2628 .WOW64_32KEY = true,
2629 .WOW64_64KEY = true,
2630 } },
2631 };
2632
2633 /// Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values.
2634 pub const READ: ACCESS_MASK = .{
2635 .STANDARD = .{
2636 .RIGHTS = .READ,
2637 .SYNCHRONIZE = false,
2638 },
2639 .SPECIFIC = .{ .KEY = .{
2640 .QUERY_VALUE = true,
2641 .ENUMERATE_SUB_KEYS = true,
2642 .NOTIFY = true,
2643 } },
2644 };
2645
2646 /// Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY access rights.
2647 pub const WRITE: ACCESS_MASK = .{
2648 .STANDARD = .{
2649 .RIGHTS = .WRITE,
2650 .SYNCHRONIZE = false,
2651 },
2652 .SPECIFIC = .{ .KEY = .{
2653 .SET_VALUE = true,
2654 .CREATE_SUB_KEY = true,
2655 } },
2656 };
2657
2658 /// Equivalent to KEY_READ.
2659 pub const EXECUTE = READ;
2660
2661 pub const ALL_ACCESS: ACCESS_MASK = .{
2662 .STANDARD = .{
2663 .RIGHTS = .ALL,
2664 .SYNCHRONIZE = false,
2665 },
2666 .SPECIFIC = .{ .KEY = .{
2667 .QUERY_VALUE = true,
2668 .SET_VALUE = true,
2669 .CREATE_SUB_KEY = true,
2670 .ENUMERATE_SUB_KEYS = true,
2671 .NOTIFY = true,
2672 .CREATE_LINK = true,
2673 } },
2674 };
2675 };
2676
2677 pub const ObjectType = packed struct(u16) {
2678 CREATE: bool = false,
2679 Reserved1: u15 = 0,
2680
2681 pub const ALL_ACCESS: ACCESS_MASK = .{
2682 .STANDARD = .{ .RIGHTS = .REQUIRED },
2683 .SPECIFIC = .{ .OBJECT_TYPE = .{
2684 .CREATE = true,
2685 } },
2686 };
2687 };
2688
2689 pub const Directory = packed struct(u16) {
2690 QUERY: bool = false,
2691 TRAVERSE: bool = false,
2692 CREATE_OBJECT: bool = false,
2693 CREATE_SUBDIRECTORY: bool = false,
2694 Reserved3: u12 = 0,
2695
2696 pub const ALL_ACCESS: ACCESS_MASK = .{
2697 .STANDARD = .{ .RIGHTS = .REQUIRED },
2698 .SPECIFIC = .{ .DIRECTORY = .{
2699 .QUERY = true,
2700 .TRAVERSE = true,
2701 .CREATE_OBJECT = true,
2702 .CREATE_SUBDIRECTORY = true,
2703 } },
2704 };
2705 };
2706
2707 pub const SymbolicLink = packed struct(u16) {
2708 QUERY: bool = false,
2709 SET: bool = false,
2710 Reserved2: u14 = 0,
2711
2712 pub const ALL_ACCESS: ACCESS_MASK = .{
2713 .STANDARD = .{ .RIGHTS = .REQUIRED },
2714 .SPECIFIC = .{ .SYMBOLIC_LINK = .{
2715 .QUERY = true,
2716 } },
2717 };
2718
2719 pub const ALL_ACCESS_EX: ACCESS_MASK = .{
2720 .STANDARD = .{ .RIGHTS = .REQUIRED },
2721 .SPECIFIC = .{ .SYMBOLIC_LINK = .{
2722 .QUERY = true,
2723 .SET = true,
2724 .Reserved2 = maxInt(@FieldType(SymbolicLink, "Reserved2")),
2725 } },
2726 };
2727 };
2728
2729 pub const Section = packed struct(u16) {
2730 QUERY: bool = false,
2731 MAP_WRITE: bool = false,
2732 MAP_READ: bool = false,
2733 MAP_EXECUTE: bool = false,
2734 EXTEND_SIZE: bool = false,
2735 /// not included in `ALL_ACCESS`
2736 MAP_EXECUTE_EXPLICIT: bool = false,
2737 Reserved6: u10 = 0,
2738
2739 pub const ALL_ACCESS: ACCESS_MASK = .{
2740 .STANDARD = .{ .RIGHTS = .REQUIRED },
2741 .SPECIFIC = .{ .SECTION = .{
2742 .QUERY = true,
2743 .MAP_WRITE = true,
2744 .MAP_READ = true,
2745 .MAP_EXECUTE = true,
2746 .EXTEND_SIZE = true,
2747 } },
2748 };
2749 };
2750
2751 pub const Session = packed struct(u16) {
2752 QUERY_ACCESS: bool = false,
2753 MODIFY_ACCESS: bool = false,
2754 Reserved2: u14 = 0,
2755
2756 pub const ALL_ACCESS: ACCESS_MASK = .{
2757 .STANDARD = .{ .RIGHTS = .REQUIRED },
2758 .SPECIFIC = .{ .SESSION = .{
2759 .QUERY_ACCESS = true,
2760 .MODIFY_ACCESS = true,
2761 } },
2762 };
2763 };
2764
2765 pub const Process = packed struct(u16) {
2766 TERMINATE: bool = false,
2767 CREATE_THREAD: bool = false,
2768 SET_SESSIONID: bool = false,
2769 VM_OPERATION: bool = false,
2770 VM_READ: bool = false,
2771 VM_WRITE: bool = false,
2772 DUP_HANDLE: bool = false,
2773 CREATE_PROCESS: bool = false,
2774 SET_QUOTA: bool = false,
2775 SET_INFORMATION: bool = false,
2776 QUERY_INFORMATION: bool = false,
2777 SUSPEND_RESUME: bool = false,
2778 QUERY_LIMITED_INFORMATION: bool = false,
2779 SET_LIMITED_INFORMATION: bool = false,
2780 Reserved14: u2 = 0,
2781
2782 pub const ALL_ACCESS: ACCESS_MASK = .{
2783 .STANDARD = .{
2784 .RIGHTS = .REQUIRED,
2785 .SYNCHRONIZE = true,
2786 },
2787 .SPECIFIC = .{ .PROCESS = .{
2788 .TERMINATE = true,
2789 .CREATE_THREAD = true,
2790 .SET_SESSIONID = true,
2791 .VM_OPERATION = true,
2792 .VM_READ = true,
2793 .VM_WRITE = true,
2794 .DUP_HANDLE = true,
2795 .CREATE_PROCESS = true,
2796 .SET_QUOTA = true,
2797 .SET_INFORMATION = true,
2798 .QUERY_INFORMATION = true,
2799 .SUSPEND_RESUME = true,
2800 .QUERY_LIMITED_INFORMATION = true,
2801 .SET_LIMITED_INFORMATION = true,
2802 .Reserved14 = maxInt(@FieldType(Process, "Reserved14")),
2803 } },
2804 };
2805 };
2806
2807 pub const Thread = packed struct(u16) {
2808 TERMINATE: bool = false,
2809 SUSPEND_RESUME: bool = false,
2810 ALERT: bool = false,
2811 GET_CONTEXT: bool = false,
2812 SET_CONTEXT: bool = false,
2813 SET_INFORMATION: bool = false,
2814 QUERY_INFORMATION: bool = false,
2815 SET_THREAD_TOKEN: bool = false,
2816 IMPERSONATE: bool = false,
2817 DIRECT_IMPERSONATION: bool = false,
2818 SET_LIMITED_INFORMATION: bool = false,
2819 QUERY_LIMITED_INFORMATION: bool = false,
2820 RESUME: bool = false,
2821 Reserved13: u3 = 0,
2822
2823 pub const ALL_ACCESS: ACCESS_MASK = .{
2824 .STANDARD = .{
2825 .RIGHTS = .REQUIRED,
2826 .SYNCHRONIZE = true,
2827 },
2828 .SPECIFIC = .{ .THREAD = .{
2829 .TERMINATE = true,
2830 .SUSPEND_RESUME = true,
2831 .ALERT = true,
2832 .GET_CONTEXT = true,
2833 .SET_CONTEXT = true,
2834 .SET_INFORMATION = true,
2835 .QUERY_INFORMATION = true,
2836 .SET_THREAD_TOKEN = true,
2837 .IMPERSONATE = true,
2838 .DIRECT_IMPERSONATION = true,
2839 .SET_LIMITED_INFORMATION = true,
2840 .QUERY_LIMITED_INFORMATION = true,
2841 .RESUME = true,
2842 .Reserved13 = maxInt(@FieldType(Thread, "Reserved13")),
2843 } },
2844 };
2845 };
2846
2847 pub const MemoryPartition = packed struct(u16) {
2848 QUERY_ACCESS: bool = false,
2849 MODIFY_ACCESS: bool = false,
2850 Required2: u14 = 0,
2851
2852 pub const ALL_ACCESS: ACCESS_MASK = .{
2853 .STANDARD = .{
2854 .RIGHTS = .REQUIRED,
2855 .SYNCHRONIZE = true,
2856 },
2857 .SPECIFIC = .{ .MEMORY_PARTITION = .{
2858 .QUERY_ACCESS = true,
2859 .MODIFY_ACCESS = true,
2860 } },
2861 };
2862 };
2863
2864 pub const TransactionManager = packed struct(u16) {
2865 QUERY_INFORMATION: bool = false,
2866 SET_INFORMATION: bool = false,
2867 RECOVER: bool = false,
2868 RENAME: bool = false,
2869 CREATE_RM: bool = false,
2870 /// The following right is intended for DTC's use only; it will be deprecated, and no one else should take a dependency on it.
2871 BIND_TRANSACTION: bool = false,
2872 Reserved6: u10 = 0,
2873
2874 pub const GENERIC_READ: ACCESS_MASK = .{
2875 .STANDARD = .{ .RIGHTS = .READ },
2876 .SPECIFIC = .{ .TRANSACTIONMANAGER = .{
2877 .QUERY_INFORMATION = true,
2878 } },
2879 };
2880
2881 pub const GENERIC_WRITE: ACCESS_MASK = .{
2882 .STANDARD = .{ .RIGHTS = .WRITE },
2883 .SPECIFIC = .{ .TRANSACTIONMANAGER = .{
2884 .SET_INFORMATION = true,
2885 .RECOVER = true,
2886 .RENAME = true,
2887 .CREATE_RM = true,
2888 } },
2889 };
2890
2891 pub const GENERIC_EXECUTE: ACCESS_MASK = .{
2892 .STANDARD = .{ .RIGHTS = .EXECUTE },
2893 .SPECIFIC = .{ .TRANSACTIONMANAGER = .{} },
2894 };
2895
2896 pub const ALL_ACCESS: ACCESS_MASK = .{
2897 .STANDARD = .{ .RIGHTS = .REQUIRED },
2898 .SPECIFIC = .{ .TRANSACTIONMANAGER = .{
2899 .QUERY_INFORMATION = true,
2900 .SET_INFORMATION = true,
2901 .RECOVER = true,
2902 .RENAME = true,
2903 .CREATE_RM = true,
2904 .BIND_TRANSACTION = true,
2905 } },
2906 };
2907 };
2908
2909 pub const Transaction = packed struct(u16) {
2910 QUERY_INFORMATION: bool = false,
2911 SET_INFORMATION: bool = false,
2912 ENLIST: bool = false,
2913 COMMIT: bool = false,
2914 ROLLBACK: bool = false,
2915 PROPAGATE: bool = false,
2916 RIGHT_RESERVED1: bool = false,
2917 Reserved7: u9 = 0,
2918
2919 pub const GENERIC_READ: ACCESS_MASK = .{
2920 .STANDARD = .{
2921 .RIGHTS = .READ,
2922 .SYNCHRONIZE = true,
2923 },
2924 .SPECIFIC = .{ .TRANSACTION = .{
2925 .QUERY_INFORMATION = true,
2926 } },
2927 };
2928
2929 pub const GENERIC_WRITE: ACCESS_MASK = .{
2930 .STANDARD = .{
2931 .RIGHTS = .WRITE,
2932 .SYNCHRONIZE = true,
2933 },
2934 .SPECIFIC = .{ .TRANSACTION = .{
2935 .SET_INFORMATION = true,
2936 .COMMIT = true,
2937 .ENLIST = true,
2938 .ROLLBACK = true,
2939 .PROPAGATE = true,
2940 } },
2941 };
2942
2943 pub const GENERIC_EXECUTE: ACCESS_MASK = .{
2944 .STANDARD = .{
2945 .RIGHTS = .EXECUTE,
2946 .SYNCHRONIZE = true,
2947 },
2948 .SPECIFIC = .{ .TRANSACTION = .{
2949 .COMMIT = true,
2950 .ROLLBACK = true,
2951 } },
2952 };
2953
2954 pub const ALL_ACCESS: ACCESS_MASK = .{
2955 .STANDARD = .{
2956 .RIGHTS = .REQUIRED,
2957 .SYNCHRONIZE = true,
2958 },
2959 .SPECIFIC = .{ .TRANSACTION = .{
2960 .QUERY_INFORMATION = true,
2961 .SET_INFORMATION = true,
2962 .COMMIT = true,
2963 .ENLIST = true,
2964 .ROLLBACK = true,
2965 .PROPAGATE = true,
2966 } },
2967 };
2968
2969 pub const RESOURCE_MANAGER_RIGHTS: ACCESS_MASK = .{
2970 .STANDARD = .{
2971 .RIGHTS = .{
2972 .READ_CONTROL = true,
2973 },
2974 .SYNCHRONIZE = true,
2975 },
2976 .SPECIFIC = .{ .TRANSACTION = .{
2977 .QUERY_INFORMATION = true,
2978 .SET_INFORMATION = true,
2979 .ENLIST = true,
2980 .ROLLBACK = true,
2981 .PROPAGATE = true,
2982 } },
2983 };
2984 };
2985
2986 pub const ResourceManager = packed struct(u16) {
2987 QUERY_INFORMATION: bool = false,
2988 SET_INFORMATION: bool = false,
2989 RECOVER: bool = false,
2990 ENLIST: bool = false,
2991 GET_NOTIFICATION: bool = false,
2992 REGISTER_PROTOCOL: bool = false,
2993 COMPLETE_PROPAGATION: bool = false,
2994 Reserved7: u9 = 0,
2995
2996 pub const GENERIC_READ: ACCESS_MASK = .{
2997 .STANDARD = .{
2998 .RIGHTS = .READ,
2999 .SYNCHRONIZE = true,
3000 },
3001 .SPECIFIC = .{ .RESOURCEMANAGER = .{
3002 .QUERY_INFORMATION = true,
3003 } },
3004 };
3005
3006 pub const GENERIC_WRITE: ACCESS_MASK = .{
3007 .STANDARD = .{
3008 .RIGHTS = .WRITE,
3009 .SYNCHRONIZE = true,
3010 },
3011 .SPECIFIC = .{ .RESOURCEMANAGER = .{
3012 .SET_INFORMATION = true,
3013 .RECOVER = true,
3014 .ENLIST = true,
3015 .GET_NOTIFICATION = true,
3016 .REGISTER_PROTOCOL = true,
3017 .COMPLETE_PROPAGATION = true,
3018 } },
3019 };
3020
3021 pub const GENERIC_EXECUTE: ACCESS_MASK = .{
3022 .STANDARD = .{
3023 .RIGHTS = .EXECUTE,
3024 .SYNCHRONIZE = true,
3025 },
3026 .SPECIFIC = .{ .RESOURCEMANAGER = .{
3027 .RECOVER = true,
3028 .ENLIST = true,
3029 .GET_NOTIFICATION = true,
3030 .COMPLETE_PROPAGATION = true,
3031 } },
3032 };
3033
3034 pub const ALL_ACCESS: ACCESS_MASK = .{
3035 .STANDARD = .{
3036 .RIGHTS = .REQUIRED,
3037 .SYNCHRONIZE = true,
3038 },
3039 .SPECIFIC = .{ .RESOURCEMANAGER = .{
3040 .QUERY_INFORMATION = true,
3041 .SET_INFORMATION = true,
3042 .RECOVER = true,
3043 .ENLIST = true,
3044 .GET_NOTIFICATION = true,
3045 .REGISTER_PROTOCOL = true,
3046 .COMPLETE_PROPAGATION = true,
3047 } },
3048 };
3049 };
3050
3051 pub const Enlistment = packed struct(u16) {
3052 QUERY_INFORMATION: bool = false,
3053 SET_INFORMATION: bool = false,
3054 RECOVER: bool = false,
3055 SUBORDINATE_RIGHTS: bool = false,
3056 SUPERIOR_RIGHTS: bool = false,
3057 Reserved5: u11 = 0,
3058
3059 pub const GENERIC_READ: ACCESS_MASK = .{
3060 .STANDARD = .{ .RIGHTS = .READ },
3061 .SPECIFIC = .{ .ENLISTMENT = .{
3062 .QUERY_INFORMATION = true,
3063 } },
3064 };
3065
3066 pub const GENERIC_WRITE: ACCESS_MASK = .{
3067 .STANDARD = .{ .RIGHTS = .WRITE },
3068 .SPECIFIC = .{ .ENLISTMENT = .{
3069 .SET_INFORMATION = true,
3070 .RECOVER = true,
3071 .SUBORDINATE_RIGHTS = true,
3072 .SUPERIOR_RIGHTS = true,
3073 } },
3074 };
3075
3076 pub const GENERIC_EXECUTE: ACCESS_MASK = .{
3077 .STANDARD = .{ .RIGHTS = .EXECUTE },
3078 .SPECIFIC = .{ .ENLISTMENT = .{
3079 .RECOVER = true,
3080 .SUBORDINATE_RIGHTS = true,
3081 .SUPERIOR_RIGHTS = true,
3082 } },
3083 };
3084
3085 pub const ALL_ACCESS: ACCESS_MASK = .{
3086 .STANDARD = .{ .RIGHTS = .REQUIRED },
3087 .SPECIFIC = .{ .ENLISTMENT = .{
3088 .QUERY_INFORMATION = true,
3089 .SET_INFORMATION = true,
3090 .RECOVER = true,
3091 .SUBORDINATE_RIGHTS = true,
3092 .SUPERIOR_RIGHTS = true,
3093 } },
3094 };
3095 };
3096
3097 pub const Event = packed struct(u16) {
3098 QUERY_STATE: bool = false,
3099 MODIFY_STATE: bool = false,
3100 Reserved2: u14 = 0,
3101
3102 pub const ALL_ACCESS: ACCESS_MASK = .{
3103 .STANDARD = .{
3104 .RIGHTS = .REQUIRED,
3105 .SYNCHRONIZE = true,
3106 },
3107 .SPECIFIC = .{ .EVENT = .{
3108 .QUERY_STATE = true,
3109 .MODIFY_STATE = true,
3110 } },
3111 };
3112 };
3113
3114 pub const Semaphore = packed struct(u16) {
3115 QUERY_STATE: bool = false,
3116 MODIFY_STATE: bool = false,
3117 Reserved2: u14 = 0,
3118
3119 pub const ALL_ACCESS: ACCESS_MASK = .{
3120 .STANDARD = .{
3121 .RIGHTS = .REQUIRED,
3122 .SYNCHRONIZE = true,
3123 },
3124 .SPECIFIC = .{ .SEMAPHORE = .{
3125 .QUERY_STATE = true,
3126 .MODIFY_STATE = true,
3127 } },
3128 };
3129 };
3130
3131 pub const Token = packed struct(u16) {
3132 ASSIGN_PRIMARY: bool = false,
3133 DUPLICATE: bool = false,
3134 IMPERSONATE: bool = false,
3135 QUERY: bool = false,
3136 QUERY_SOURCE: bool = false,
3137 ADJUST_PRIVILEGES: bool = false,
3138 ADJUST_GROUPS: bool = false,
3139 ADJUST_DEFAULT: bool = false,
3140 ADJUST_SESSIONID: bool = false,
3141 Reserved9: u7 = 0,
3142
3143 pub const ALL_ACCESS_P: ACCESS_MASK = .{
3144 .STANDARD = .{ .RIGHTS = .REQUIRED },
3145 .SPECIFIC = .{ .TOKEN = .{
3146 .ASSIGN_PRIMARY = true,
3147 .DUPLICATE = true,
3148 .IMPERSONATE = true,
3149 .QUERY = true,
3150 .QUERY_SOURCE = true,
3151 .ADJUST_PRIVILEGES = true,
3152 .ADJUST_GROUPS = true,
3153 .ADJUST_DEFAULT = true,
3154 } },
3155 };
3156
3157 pub const ALL_ACCESS: ACCESS_MASK = .{
3158 .STANDARD = .{ .RIGHTS = .REQUIRED },
3159 .SPECIFIC = .{ .TOKEN = .{
3160 .ASSIGN_PRIMARY = true,
3161 .DUPLICATE = true,
3162 .IMPERSONATE = true,
3163 .QUERY = true,
3164 .QUERY_SOURCE = true,
3165 .ADJUST_PRIVILEGES = true,
3166 .ADJUST_GROUPS = true,
3167 .ADJUST_DEFAULT = true,
3168 .ADJUST_SESSIONID = true,
3169 } },
3170 };
3171
3172 pub const READ: ACCESS_MASK = .{
3173 .STANDARD = .{ .RIGHTS = .READ },
3174 .SPECIFIC = .{ .TOKEN = .{
3175 .QUERY = true,
3176 } },
3177 };
3178
3179 pub const WRITE: ACCESS_MASK = .{
3180 .STANDARD = .{ .RIGHTS = .WRITE },
3181 .SPECIFIC = .{ .TOKEN = .{
3182 .ADJUST_PRIVILEGES = true,
3183 .ADJUST_GROUPS = true,
3184 .ADJUST_DEFAULT = true,
3185 } },
3186 };
3187
3188 pub const EXECUTE: ACCESS_MASK = .{
3189 .STANDARD = .{ .RIGHTS = .EXECUTE },
3190 .SPECIFIC = .{ .TOKEN = .{} },
3191 };
3192
3193 pub const TRUST_CONSTRAINT_MASK: ACCESS_MASK = .{
3194 .STANDARD = .{ .RIGHTS = .READ },
3195 .SPECIFIC = .{ .TOKEN = .{
3196 .QUERY = true,
3197 .QUERY_SOURCE = true,
3198 } },
3199 };
3200
3201 pub const TRUST_ALLOWED_MASK: ACCESS_MASK = .{
3202 .STANDARD = .{ .RIGHTS = .READ },
3203 .SPECIFIC = .{ .TOKEN = .{
3204 .QUERY = true,
3205 .QUERY_SOURCE = true,
3206 .DUPLICATE = true,
3207 .IMPERSONATE = true,
3208 } },
3209 };
3210 };
3211
3212 pub const JobObject = packed struct(u16) {
3213 ASSIGN_PROCESS: bool = false,
3214 SET_ATTRIBUTES: bool = false,
3215 QUERY: bool = false,
3216 TERMINATE: bool = false,
3217 SET_SECURITY_ATTRIBUTES: bool = false,
3218 IMPERSONATE: bool = false,
3219 Reserved6: u10 = 0,
3220
3221 pub const ALL_ACCESS: ACCESS_MASK = .{
3222 .STANDARD = .{
3223 .RIGHTS = .REQUIRED,
3224 .SYNCHRONIZE = true,
3225 },
3226 .SPECIFIC = .{ .JOB_OBJECT = .{
3227 .ASSIGN_PROCESS = true,
3228 .SET_ATTRIBUTES = true,
3229 .QUERY = true,
3230 .TERMINATE = true,
3231 .SET_SECURITY_ATTRIBUTES = true,
3232 .IMPERSONATE = true,
3233 } },
3234 };
3235 };
3236
3237 pub const Mutant = packed struct(u16) {
3238 QUERY_STATE: bool = false,
3239 Reserved1: u15 = 0,
3240
3241 pub const ALL_ACCESS: ACCESS_MASK = .{
3242 .STANDARD = .{
3243 .RIGHTS = .REQUIRED,
3244 .SYNCHRONIZE = true,
3245 },
3246 .SPECIFIC = .{ .MUTANT = .{
3247 .QUERY_STATE = true,
3248 } },
3249 };
3250 };
3251
3252 pub const Timer = packed struct(u16) {
3253 QUERY_STATE: bool = false,
3254 MODIFY_STATE: bool = false,
3255 Reserved2: u14 = 0,
3256
3257 pub const ALL_ACCESS: ACCESS_MASK = .{
3258 .STANDARD = .{
3259 .RIGHTS = .REQUIRED,
3260 .SYNCHRONIZE = true,
3261 },
3262 .SPECIFIC = .{ .TIMER = .{
3263 .QUERY_STATE = true,
3264 .MODIFY_STATE = true,
3265 } },
3266 };
3267 };
3268
3269 pub const IoCompletion = packed struct(u16) {
3270 Reserved0: u1 = 0,
3271 MODIFY_STATE: bool = false,
3272 Reserved2: u14 = 0,
3273
3274 pub const ALL_ACCESS: ACCESS_MASK = .{
3275 .STANDARD = .{ .RIGHTS = .REQUIRED, .SYNCHRONIZE = true },
3276 .SPECIFIC = .{ .IO_COMPLETION = .{
3277 .Reserved0 = maxInt(@FieldType(IoCompletion, "Reserved0")),
3278 .MODIFY_STATE = true,
3279 } },
3280 };
3281 };
3282
3283 pub const RIGHTS_ALL: Specific = .{ .bits = maxInt(@FieldType(Specific, "bits")) };
3284 };
3285
3286 pub const Standard = packed struct(u5) {
3287 RIGHTS: Rights = .{},
3288 SYNCHRONIZE: bool = false,
3289
3290 pub const RIGHTS_ALL: Standard = .{
3291 .RIGHTS = .ALL,
3292 .SYNCHRONIZE = true,
3293 };
3294
3295 pub const Rights = packed struct(u4) {
3296 DELETE: bool = false,
3297 READ_CONTROL: bool = false,
3298 WRITE_DAC: bool = false,
3299 WRITE_OWNER: bool = false,
3300
3301 pub const REQUIRED: Rights = .{
3302 .DELETE = true,
3303 .READ_CONTROL = true,
3304 .WRITE_DAC = true,
3305 .WRITE_OWNER = true,
3306 };
3307
3308 pub const READ: Rights = .{
3309 .READ_CONTROL = true,
3310 };
3311 pub const WRITE: Rights = .{
3312 .READ_CONTROL = true,
3313 };
3314 pub const EXECUTE: Rights = .{
3315 .READ_CONTROL = true,
3316 };
3317
3318 pub const ALL = REQUIRED;
3319 };
3320 };
3321
3322 pub const Generic = packed struct(u4) {
3323 ALL: bool = false,
3324 EXECUTE: bool = false,
3325 WRITE: bool = false,
3326 READ: bool = false,
3327 };
3328};
3329
3330pub const DEVICE_TYPE = packed struct(ULONG) {
3331 FileDevice: CTL_CODE.FILE_DEVICE,
3332 Reserved16: u16 = 0,
3333};
3334
3335pub const FS_INFORMATION_CLASS = enum(c_int) {
3336 Volume = 1,
3337 Label = 2,
3338 Size = 3,
3339 Device = 4,
3340 Attribute = 5,
3341 Control = 6,
3342 FullSize = 7,
3343 ObjectId = 8,
3344 DriverPath = 9,
3345 VolumeFlags = 10,
3346 SectorSize = 11,
3347 DataCopy = 12,
3348 MetadataSize = 13,
3349 FullSizeEx = 14,
3350 Guid = 15,
3351 _,
3352
3353 pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".field_names.len;
3354};
3355
3356pub const SECTION_INHERIT = enum(c_int) {
3357 Share = 1,
3358 Unmap = 2,
3359};
3360
3361pub const PAGE = packed struct(ULONG) {
3362 NOACCESS: bool = false,
3363 READONLY: bool = false,
3364 READWRITE: bool = false,
3365 WRITECOPY: bool = false,
3366
3367 EXECUTE: bool = false,
3368 EXECUTE_READ: bool = false,
3369 EXECUTE_READWRITE: bool = false,
3370 EXECUTE_WRITECOPY: bool = false,
3371
3372 GUARD: bool = false,
3373 NOCACHE: bool = false,
3374 WRITECOMBINE: bool = false,
3375
3376 GRAPHICS_NOACCESS: bool = false,
3377 GRAPHICS_READONLY: bool = false,
3378 GRAPHICS_READWRITE: bool = false,
3379 GRAPHICS_EXECUTE: bool = false,
3380 GRAPHICS_EXECUTE_READ: bool = false,
3381 GRAPHICS_EXECUTE_READWRITE: bool = false,
3382 GRAPHICS_COHERENT: bool = false,
3383 GRAPHICS_NOCACHE: bool = false,
3384
3385 Reserved19: u12 = 0,
3386
3387 REVERT_TO_FILE_MAP: bool = false,
3388
3389 pub fn fromProtection(protection: std.process.MemoryProtection) ?PAGE {
3390 // TODO https://github.com/ziglang/zig/issues/22214
3391 return switch (@as(u3, @bitCast(protection))) {
3392 0b000 => .{ .NOACCESS = true },
3393 0b001 => .{ .READONLY = true },
3394 0b010 => null,
3395 0b011 => .{ .READWRITE = true },
3396 0b100 => .{ .EXECUTE = true },
3397 0b101 => .{ .EXECUTE_READ = true },
3398 0b110 => null,
3399 0b111 => .{ .EXECUTE_READWRITE = true },
3400 };
3401 }
3402};
3403
3404pub const MEM = struct {
3405 pub const ALLOCATE = packed struct(ULONG) {
3406 Reserved0: u12 = 0,
3407 COMMIT: bool = false,
3408 RESERVE: bool = false,
3409 REPLACE_PLACEHOLDER: bool = false,
3410 Reserved15: u3 = 0,
3411 RESERVE_PLACEHOLDER: bool = false,
3412 RESET: bool = false,
3413 TOP_DOWN: bool = false,
3414 WRITE_WATCH: bool = false,
3415 PHYSICAL: bool = false,
3416 Reserved23: u1 = 0,
3417 RESET_UNDO: bool = false,
3418 Reserved25: u4 = 0,
3419 LARGE_PAGES: bool = false,
3420 Reserved30: u1 = 0,
3421 @"4MB_PAGES": bool = false,
3422
3423 pub const @"64K_PAGES": ALLOCATE = .{
3424 .LARGE_PAGES = true,
3425 .PHYSICAL = true,
3426 };
3427 };
3428
3429 pub const FREE = packed struct(ULONG) {
3430 COALESCE_PLACEHOLDERS: bool = false,
3431 PRESERVE_PLACEHOLDER: bool = false,
3432 Reserved2: u12 = 0,
3433 DECOMMIT: bool = false,
3434 RELEASE: bool = false,
3435 FREE: bool = false,
3436 Reserved17: u15 = 0,
3437 };
3438
3439 pub const MAP = packed struct(ULONG) {
3440 Reserved0: u13 = 0,
3441 RESERVE: bool = false,
3442 REPLACE_PLACEHOLDER: bool = false,
3443 Reserved15: u14 = 0,
3444 LARGE_PAGES: bool = false,
3445 Reserved30: u2 = 0,
3446 };
3447
3448 pub const UNMAP = packed struct(ULONG) {
3449 WITH_TRANSIENT_BOOST: bool = false,
3450 PRESERVE_PLACEHOLDER: bool = false,
3451 Reserved2: u30 = 0,
3452 };
3453
3454 pub const EXTENDED_PARAMETER = extern struct {
3455 s: packed struct(ULONG64) {
3456 Type: TYPE,
3457 Reserved: u56,
3458 },
3459 u: extern union {
3460 ULong64: ULONG64,
3461 Pointer: PVOID,
3462 Size: SIZE_T,
3463 Handle: HANDLE,
3464 ULong: ULONG,
3465 },
3466
3467 pub const TYPE = enum(u8) {
3468 InvalidType = 0,
3469 AddressRequirements,
3470 NumaNode,
3471 PartitionHandle,
3472 UserPhysicalHandle,
3473 AttributeFlags,
3474 ImageMachine,
3475 _,
3476
3477 pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".field_names.len;
3478 };
3479 };
3480};
3481
3482pub const SEC = packed struct(ULONG) {
3483 Reserved0: u17 = 0,
3484 HUGE_PAGES: bool = false,
3485 PARTITION_OWNER_HANDLE: bool = false,
3486 @"64K_PAGES": bool = false,
3487 Reserved19: u3 = 0,
3488 FILE: bool = false,
3489 IMAGE: bool = false,
3490 PROTECTED_IMAGE: bool = false,
3491 RESERVE: bool = false,
3492 COMMIT: bool = false,
3493 NOCACHE: bool = false,
3494 Reserved29: u1 = 0,
3495 WRITECOMBINE: bool = false,
3496 LARGE_PAGES: bool = false,
3497
3498 pub const IMAGE_NO_EXECUTE: SEC = .{
3499 .IMAGE = true,
3500 .NOCACHE = true,
3501 };
3502};
3503
3504pub const ERESOURCE = opaque {};
3505
3506// ref: shared/ntdef.h
3507
3508pub const EVENT_TYPE = enum(c_int) {
3509 Notification,
3510 Synchronization,
3511};
3512
3513pub const TIMER_TYPE = enum(c_int) {
3514 Notification,
3515 Synchronization,
3516};
3517
3518pub const WAIT_TYPE = enum(c_int) {
3519 All,
3520 Any,
3521};
3522
3523pub const LOGICAL = ULONG;
3524
3525pub const NTSTATUS = @import("windows/ntstatus.zig").NTSTATUS;
3526
3527// ref: um/heapapi.h
3528
3529pub fn GetProcessHeap() ?*HEAP {
3530 return peb().ProcessHeap;
3531}
3532
3533// ref none
3534
3535pub fn GetCurrentProcess() HANDLE {
3536 const process_pseudo_handle: usize = @bitCast(@as(isize, -1));
3537 return @ptrFromInt(process_pseudo_handle);
3538}
3539
3540pub fn GetCurrentProcessId() DWORD {
3541 return @truncate(@intFromPtr(teb().ClientId.UniqueProcess));
3542}
3543
3544pub fn GetCurrentThread() HANDLE {
3545 const thread_pseudo_handle: usize = @bitCast(@as(isize, -2));
3546 return @ptrFromInt(thread_pseudo_handle);
3547}
3548
3549pub fn GetCurrentThreadId() DWORD {
3550 return @truncate(@intFromPtr(teb().ClientId.UniqueThread));
3551}
3552
3553pub fn GetLastError() Win32Error {
3554 return teb().LastErrorValue;
3555}
3556
3557pub fn CloseHandle(hObject: HANDLE) void {
3558 switch (ntdll.NtClose(hObject)) {
3559 .SUCCESS => {},
3560 else => |status| unexpectedStatus(status) catch {},
3561 }
3562}
3563
3564pub const CreateProcessError = error{
3565 FileNotFound,
3566 AccessDenied,
3567 InvalidName,
3568 NameTooLong,
3569 InvalidExe,
3570 SystemResources,
3571 FileBusy,
3572 Unexpected,
3573};
3574
3575pub const CreateProcessFlags = packed struct(u32) {
3576 debug_process: bool = false,
3577 debug_only_this_process: bool = false,
3578 create_suspended: bool = false,
3579 detached_process: bool = false,
3580 create_new_console: bool = false,
3581 normal_priority_class: bool = false,
3582 idle_priority_class: bool = false,
3583 high_priority_class: bool = false,
3584 realtime_priority_class: bool = false,
3585 create_new_process_group: bool = false,
3586 create_unicode_environment: bool = false,
3587 create_separate_wow_vdm: bool = false,
3588 create_shared_wow_vdm: bool = false,
3589 create_forcedos: bool = false,
3590 below_normal_priority_class: bool = false,
3591 above_normal_priority_class: bool = false,
3592 inherit_parent_affinity: bool = false,
3593 inherit_caller_priority: bool = false,
3594 create_protected_process: bool = false,
3595 extended_startupinfo_present: bool = false,
3596 process_mode_background_begin: bool = false,
3597 process_mode_background_end: bool = false,
3598 create_secure_process: bool = false,
3599 _reserved: bool = false,
3600 create_breakaway_from_job: bool = false,
3601 create_preserve_code_authz_level: bool = false,
3602 create_default_error_mode: bool = false,
3603 create_no_window: bool = false,
3604 profile_user: bool = false,
3605 profile_kernel: bool = false,
3606 profile_server: bool = false,
3607 create_ignore_system_default: bool = false,
3608};
3609
3610pub fn teb() *TEB {
3611 if (builtin.zig_backend == .stage2_c) return @ptrCast(@alignCast(struct {
3612 /// This is a workaround for the C backend until zig has the ability to put
3613 /// C code in inline assembly.
3614 extern fn zig_windows_teb() callconv(.c) *anyopaque;
3615 }.zig_windows_teb()));
3616 switch (native_arch) {
3617 .thumb => return asm (
3618 \\ mrc p15, 0, %[ptr], c13, c0, 2
3619 : [ptr] "=r" (-> *TEB),
3620 ),
3621 .aarch64 => return asm (
3622 \\ mov %[ptr], x18
3623 : [ptr] "=r" (-> *TEB),
3624 ),
3625 .x86 => {
3626 comptime assert(
3627 @offsetOf(TEB, "NtTib") + @offsetOf(@FieldType(TEB, "NtTib"), "Self") == 0x18,
3628 );
3629 return asm (
3630 \\ movl %%fs:0x18, %[ptr]
3631 : [ptr] "=r" (-> *TEB),
3632 );
3633 },
3634 .x86_64 => {
3635 comptime assert(
3636 @offsetOf(TEB, "NtTib") + @offsetOf(@FieldType(TEB, "NtTib"), "Self") == 0x30,
3637 );
3638 return asm (
3639 \\ movq %%gs:0x30, %[ptr]
3640 : [ptr] "=r" (-> *TEB),
3641 );
3642 },
3643 else => @compileError("unsupported arch"),
3644 }
3645}
3646
3647pub fn peb() *PEB {
3648 if (builtin.zig_backend == .stage2_c) switch (native_arch) {
3649 .x86, .x86_64 => return @ptrCast(@alignCast(struct {
3650 /// This is a workaround for the C backend until zig has the ability to put
3651 /// C code in inline assembly.
3652 extern fn zig_windows_peb() callconv(.c) *anyopaque;
3653 }.zig_windows_peb())),
3654 else => {},
3655 } else switch (native_arch) {
3656 .aarch64 => {
3657 comptime assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x60);
3658 return asm (
3659 \\ ldr %[ptr], [x18, #0x60]
3660 : [ptr] "=r" (-> *PEB),
3661 );
3662 },
3663 .x86 => {
3664 comptime assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x30);
3665 return asm (
3666 \\ movl %%fs:0x30, %[ptr]
3667 : [ptr] "=r" (-> *PEB),
3668 );
3669 },
3670 .x86_64 => {
3671 comptime assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x60);
3672 return asm (
3673 \\ movq %%gs:0x60, %[ptr]
3674 : [ptr] "=r" (-> *PEB),
3675 );
3676 },
3677 else => {},
3678 }
3679 return teb().ProcessEnvironmentBlock;
3680}
3681
3682/// A file time is a 64-bit value that represents the number of 100-nanosecond
3683/// intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated
3684/// Universal Time (UTC).
3685/// This function returns the number of nanoseconds since the canonical epoch,
3686/// which is the POSIX one (Jan 01, 1970 AD).
3687pub fn fromSysTime(hns: i64) Io.Timestamp {
3688 const adjusted_epoch: i128 = hns + std.time.epoch.windows * (std.time.ns_per_s / 100);
3689 return .fromNanoseconds(@intCast(adjusted_epoch * 100));
3690}
3691
3692pub fn toSysTime(ns: Io.Timestamp) i64 {
3693 const hns = @divFloor(ns.nanoseconds, 100);
3694 return @as(i64, @intCast(hns)) - std.time.epoch.windows * (std.time.ns_per_s / 100);
3695}
3696
3697/// Use RtlUpcaseUnicodeChar on Windows when not in comptime to avoid including a
3698/// redundant copy of the uppercase data.
3699pub inline fn toUpperWtf16(c: u16) u16 {
3700 return (if (builtin.os.tag != .windows or @inComptime()) nls.upcaseW else ntdll.RtlUpcaseUnicodeChar)(c);
3701}
3702
3703/// Compares two WTF16 strings using the equivalent functionality of
3704/// `RtlEqualUnicodeString` (with case insensitive comparison enabled).
3705/// This function can be called on any target.
3706pub fn eqlIgnoreCaseWtf16(a: []const u16, b: []const u16) bool {
3707 if (@inComptime() or builtin.os.tag != .windows) {
3708 // This function compares the strings code unit by code unit (aka u16-to-u16),
3709 // so any length difference implies inequality. In other words, there's no possible
3710 // conversion that changes the number of WTF-16 code units needed for the uppercase/lowercase
3711 // version in the conversion table since only codepoints <= max(u16) are eligible
3712 // for conversion at all.
3713 if (a.len != b.len) return false;
3714
3715 for (a, b) |a_c, b_c| {
3716 // The slices are always WTF-16 LE, so need to convert the elements to native
3717 // endianness for the uppercasing
3718 const a_c_native = std.mem.littleToNative(u16, a_c);
3719 const b_c_native = std.mem.littleToNative(u16, b_c);
3720 if (a_c != b_c and toUpperWtf16(a_c_native) != toUpperWtf16(b_c_native)) {
3721 return false;
3722 }
3723 }
3724 return true;
3725 }
3726 // Use RtlEqualUnicodeString on Windows when not in comptime to avoid including a
3727 // redundant copy of the uppercase data.
3728 return ntdll.RtlEqualUnicodeString(&.init(a), &.init(b), .TRUE).toBool();
3729}
3730
3731/// Compares two WTF-8 strings using the equivalent functionality of
3732/// `RtlEqualUnicodeString` (with case insensitive comparison enabled).
3733/// This function can be called on any target.
3734/// Assumes `a` and `b` are valid WTF-8.
3735pub fn eqlIgnoreCaseWtf8(a: []const u8, b: []const u8) bool {
3736 // A length equality check is not possible here because there are
3737 // some codepoints that have a different length uppercase UTF-8 representations
3738 // than their lowercase counterparts, e.g. U+0250 (2 bytes) <-> U+2C6F (3 bytes).
3739 // There are 7 such codepoints in the uppercase data used by Windows.
3740
3741 var a_wtf8_it = std.unicode.Wtf8View.initUnchecked(a).iterator();
3742 var b_wtf8_it = std.unicode.Wtf8View.initUnchecked(b).iterator();
3743
3744 while (true) {
3745 const a_cp = a_wtf8_it.nextCodepoint() orelse break;
3746 const b_cp = b_wtf8_it.nextCodepoint() orelse return false;
3747
3748 if (a_cp <= maxInt(u16) and b_cp <= maxInt(u16)) {
3749 if (a_cp != b_cp and toUpperWtf16(@intCast(a_cp)) != toUpperWtf16(@intCast(b_cp))) {
3750 return false;
3751 }
3752 } else if (a_cp != b_cp) {
3753 return false;
3754 }
3755 }
3756 // Make sure there are no leftover codepoints in b
3757 if (b_wtf8_it.nextCodepoint() != null) return false;
3758
3759 return true;
3760}
3761
3762fn testEqlIgnoreCase(comptime expect_eql: bool, comptime a: []const u8, comptime b: []const u8) !void {
3763 try std.testing.expectEqual(expect_eql, eqlIgnoreCaseWtf8(a, b));
3764 try std.testing.expectEqual(expect_eql, eqlIgnoreCaseWtf16(
3765 std.unicode.utf8ToUtf16LeStringLiteral(a),
3766 std.unicode.utf8ToUtf16LeStringLiteral(b),
3767 ));
3768
3769 try comptime std.testing.expect(expect_eql == eqlIgnoreCaseWtf8(a, b));
3770 try comptime std.testing.expect(expect_eql == eqlIgnoreCaseWtf16(
3771 std.unicode.utf8ToUtf16LeStringLiteral(a),
3772 std.unicode.utf8ToUtf16LeStringLiteral(b),
3773 ));
3774}
3775
3776test "eqlIgnoreCaseWtf16/Wtf8" {
3777 try testEqlIgnoreCase(true, "\x01 a B Λ ɐ", "\x01 A b λ Ɐ");
3778 // does not do case-insensitive comparison for codepoints >= U+10000
3779 try testEqlIgnoreCase(false, "𐓏", "𐓷");
3780}
3781
3782/// The error type for `removeDotDirsSanitized`
3783pub const RemoveDotDirsError = error{TooManyParentDirs};
3784
3785/// Removes '.' and '..' path components from a "sanitized relative path".
3786/// A "sanitized path" is one where:
3787/// 1) all forward slashes have been replaced with back slashes
3788/// 2) all repeating back slashes have been collapsed
3789/// 3) the path is a relative one (does not start with a back slash)
3790pub fn removeDotDirsSanitized(comptime T: type, path: []T) RemoveDotDirsError!usize {
3791 assert(path.len == 0 or path[0] != '\\');
3792
3793 var write_idx: usize = 0;
3794 var read_idx: usize = 0;
3795 while (read_idx < path.len) {
3796 if (path[read_idx] == '.') {
3797 if (read_idx + 1 == path.len)
3798 return write_idx;
3799
3800 const after_dot = path[read_idx + 1];
3801 if (after_dot == '\\') {
3802 read_idx += 2;
3803 continue;
3804 }
3805 if (after_dot == '.' and (read_idx + 2 == path.len or path[read_idx + 2] == '\\')) {
3806 if (write_idx == 0) return error.TooManyParentDirs;
3807 assert(write_idx >= 2);
3808 write_idx -= 1;
3809 while (true) {
3810 write_idx -= 1;
3811 if (write_idx == 0) break;
3812 if (path[write_idx] == '\\') {
3813 write_idx += 1;
3814 break;
3815 }
3816 }
3817 if (read_idx + 2 == path.len)
3818 return write_idx;
3819 read_idx += 3;
3820 continue;
3821 }
3822 }
3823
3824 // skip to the next path separator
3825 while (true) : (read_idx += 1) {
3826 if (read_idx == path.len)
3827 return write_idx;
3828 path[write_idx] = path[read_idx];
3829 write_idx += 1;
3830 if (path[read_idx] == '\\')
3831 break;
3832 }
3833 read_idx += 1;
3834 }
3835 return write_idx;
3836}
3837
3838/// Normalizes a Windows path with the following steps:
3839/// 1) convert all forward slashes to back slashes
3840/// 2) collapse duplicate back slashes
3841/// 3) remove '.' and '..' directory parts
3842/// Returns the length of the new path.
3843pub fn normalizePath(comptime T: type, path: []T) RemoveDotDirsError!usize {
3844 mem.replaceScalar(T, path, '/', '\\');
3845 const new_len = mem.collapseRepeatsLen(T, path, '\\');
3846
3847 const prefix_len: usize = init: {
3848 if (new_len >= 1 and path[0] == '\\') break :init 1;
3849 if (new_len >= 2 and path[1] == ':')
3850 break :init if (new_len >= 3 and path[2] == '\\') @as(usize, 3) else @as(usize, 2);
3851 break :init 0;
3852 };
3853
3854 return prefix_len + try removeDotDirsSanitized(T, path[prefix_len..new_len]);
3855}
3856
3857/// Returns true if the path starts with `\??\`, which is indicative of an NT path
3858/// but is not enough to fully distinguish between NT paths and Win32 paths, as
3859/// `\??\` is not actually a distinct prefix but rather the path to a special virtual
3860/// folder in the Object Manager.
3861///
3862/// For example, `\Device\HarddiskVolume2` and `\DosDevices\C:` are also NT paths but
3863/// cannot be distinguished as such by their prefix.
3864///
3865/// So, inferring whether a path is an NT path or a Win32 path is usually a mistake;
3866/// that information should instead be known ahead-of-time.
3867///
3868/// If `T` is `u16`, then `path` should be encoded as WTF-16LE.
3869pub fn hasCommonNtPrefix(comptime T: type, path: []const T) bool {
3870 // Must be exactly \??\, forward slashes are not allowed
3871 const expected_wtf8_prefix = "\\??\\";
3872 const expected_prefix = switch (T) {
3873 u8 => expected_wtf8_prefix,
3874 u16 => std.unicode.wtf8ToWtf16LeStringLiteral(expected_wtf8_prefix),
3875 else => @compileError("unsupported type: " ++ @typeName(T)),
3876 };
3877 return mem.startsWith(T, path, expected_prefix);
3878}
3879
3880/// Similar to `RtlNtPathNameToDosPathName` but does not do any heap allocation.
3881/// The possible transformations are:
3882/// \??\C:\Some\Path -> C:\Some\Path
3883/// \??\UNC\server\share\foo -> \\server\share\foo
3884/// If the path does not have the NT namespace prefix, then `error.NotNtPath` is returned.
3885///
3886/// Functionality is based on the ReactOS test cases found here:
3887/// https://github.com/reactos/reactos/blob/master/modules/rostests/apitests/ntdll/RtlNtPathNameToDosPathName.c
3888///
3889/// `path` should be encoded as WTF-16LE.
3890///
3891/// Supports in-place modification (`path` and `out` may refer to the same slice).
3892pub fn ntToWin32Namespace(path: []const u16, out: []u16) error{ NameTooLong, NotNtPath }![]u16 {
3893 if (path.len > PATH_MAX_WIDE) return error.NameTooLong;
3894 if (!hasCommonNtPrefix(u16, path)) return error.NotNtPath;
3895
3896 var dest_index: usize = 0;
3897 var after_prefix = path[4..]; // after the `\??\`
3898 // The prefix \??\UNC\ means this is a UNC path, in which case the
3899 // `\??\UNC\` should be replaced by `\\` (two backslashes)
3900 const is_unc = after_prefix.len >= 4 and
3901 eqlIgnoreCaseWtf16(after_prefix[0..3], std.unicode.utf8ToUtf16LeStringLiteral("UNC")) and
3902 std.fs.path.PathType.windows.isSep(u16, after_prefix[3]);
3903 const win32_len = path.len - @as(usize, if (is_unc) 6 else 4);
3904 if (out.len < win32_len) return error.NameTooLong;
3905 if (is_unc) {
3906 out[0] = comptime std.mem.nativeToLittle(u16, '\\');
3907 dest_index += 1;
3908 // We want to include the last `\` of `\??\UNC\`
3909 after_prefix = path[7..];
3910 }
3911 @memmove(out[dest_index..][0..after_prefix.len], after_prefix);
3912 return out[0..win32_len];
3913}
3914
3915test ntToWin32Namespace {
3916 const L = std.unicode.utf8ToUtf16LeStringLiteral;
3917
3918 var mutable_unc_path_buf = L("\\??\\UNC\\path1\\path2").*;
3919 try std.testing.expectEqualSlices(u16, L("\\\\path1\\path2"), try ntToWin32Namespace(&mutable_unc_path_buf, &mutable_unc_path_buf));
3920
3921 var mutable_path_buf = L("\\??\\C:\\test\\").*;
3922 try std.testing.expectEqualSlices(u16, L("C:\\test\\"), try ntToWin32Namespace(&mutable_path_buf, &mutable_path_buf));
3923
3924 var too_small_buf: [6]u16 = undefined;
3925 try std.testing.expectError(error.NameTooLong, ntToWin32Namespace(L("\\??\\C:\\test"), &too_small_buf));
3926}
3927
3928inline fn MAKELANGID(p: c_ushort, s: c_ushort) LANGID {
3929 return (s << 10) | p;
3930}
3931
3932/// Call this when you made a windows DLL call or something that does SetLastError
3933/// and you get an unexpected error.
3934pub fn unexpectedError(err: Win32Error) UnexpectedError {
3935 @branchHint(.cold);
3936 if (std.options.unexpected_error_tracing) {
3937 std.debug.print("error.Unexpected: GetLastError({d}): {t}\n", .{ err, err });
3938 std.debug.dumpCurrentStackTrace(.{ .first_address = @returnAddress() });
3939 }
3940 return error.Unexpected;
3941}
3942
3943/// Call this when you made a windows NtDll call
3944/// and you get an unexpected status.
3945pub fn unexpectedStatus(status: NTSTATUS) UnexpectedError {
3946 if (std.options.unexpected_error_tracing) {
3947 std.debug.print("error.Unexpected NTSTATUS=0x{x} ({s})\n", .{
3948 @backingInt(status),
3949 std.enums.tagName(NTSTATUS, status) orelse "<unnamed>",
3950 });
3951 std.debug.dumpCurrentStackTrace(.{ .first_address = @returnAddress() });
3952 }
3953 return error.Unexpected;
3954}
3955
3956pub fn statusBug(status: NTSTATUS) UnexpectedError {
3957 switch (builtin.mode) {
3958 .debug => std.debug.panic("programmer bug caused syscall status: 0x{x} ({s})", .{
3959 @backingInt(status),
3960 std.enums.tagName(NTSTATUS, status) orelse "<unnamed>",
3961 }),
3962 else => return error.Unexpected,
3963 }
3964}
3965
3966pub fn errorBug(err: Win32Error) UnexpectedError {
3967 switch (builtin.mode) {
3968 .debug => std.debug.panic("programmer bug caused syscall error: 0x{x} ({s})", .{
3969 @backingInt(err),
3970 std.enums.tagName(Win32Error, err) orelse "<unnamed>",
3971 }),
3972 else => return error.Unexpected,
3973 }
3974}
3975
3976pub const Win32Error = @import("windows/win32error.zig").Win32Error;
3977pub const LANG = @import("windows/lang.zig");
3978pub const SUBLANG = @import("windows/sublang.zig");
3979
3980pub const BOOL = Bool(c_int);
3981pub const BOOLEAN = Bool(BYTE);
3982pub const BYTE = u8;
3983pub const CHAR = u8;
3984pub const UCHAR = u8;
3985pub const FLOAT = f32;
3986pub const HANDLE = *anyopaque;
3987pub const HCRYPTPROV = ULONG_PTR;
3988pub const ATOM = u16;
3989pub const HBRUSH = *opaque {};
3990pub const HCURSOR = *opaque {};
3991pub const HICON = *opaque {};
3992pub const HINSTANCE = *opaque {};
3993pub const HMENU = *opaque {};
3994pub const HMODULE = *opaque {};
3995pub const HWND = *opaque {};
3996pub const HDC = *opaque {};
3997pub const HGLRC = *opaque {};
3998pub const FARPROC = *opaque {};
3999pub const PROC = *opaque {};
4000pub const INT = c_int;
4001pub const LPCSTR = [*:0]const CHAR;
4002pub const LPCVOID = *const anyopaque;
4003pub const LPSTR = [*:0]CHAR;
4004pub const LPVOID = *anyopaque;
4005pub const LPWSTR = [*:0]WCHAR;
4006pub const LPCWSTR = [*:0]const WCHAR;
4007pub const PVOID = *anyopaque;
4008pub const PWSTR = [*:0]WCHAR;
4009pub const PCWSTR = [*:0]const WCHAR;
4010/// Allocated by SysAllocString, freed by SysFreeString
4011pub const BSTR = [*:0]WCHAR;
4012pub const SIZE_T = usize;
4013pub const UINT = c_uint;
4014pub const ULONG_PTR = usize;
4015pub const LONG_PTR = isize;
4016pub const DWORD_PTR = ULONG_PTR;
4017pub const WCHAR = u16;
4018pub const WORD = u16;
4019pub const DWORD = u32;
4020pub const DWORD64 = u64;
4021pub const LARGE_INTEGER = i64;
4022pub const ULARGE_INTEGER = u64;
4023pub const USHORT = u16;
4024pub const SHORT = i16;
4025pub const ULONG = u32;
4026pub const LONG = i32;
4027pub const ULONG64 = u64;
4028pub const ULONGLONG = u64;
4029pub const LONGLONG = i64;
4030pub const LANGID = c_ushort;
4031pub const COLORREF = DWORD;
4032
4033pub const LPARAM = LONG_PTR;
4034
4035pub const va_list = *opaque {};
4036
4037pub const TCHAR = @compileError("Deprecated: choose between `CHAR` or `WCHAR` directly instead.");
4038pub const LPTSTR = @compileError("Deprecated: choose between `LPSTR` or `LPWSTR` directly instead.");
4039pub const LPCTSTR = @compileError("Deprecated: choose between `LPCSTR` or `LPCWSTR` directly instead.");
4040pub const PTSTR = @compileError("Deprecated: choose between `PSTR` or `PWSTR` directly instead.");
4041pub const PCTSTR = @compileError("Deprecated: choose between `PCSTR` or `PCWSTR` directly instead.");
4042
4043fn STRING(comptime C: type) type {
4044 return extern struct {
4045 Length: USHORT,
4046 MaximumLength: USHORT,
4047 Buffer: ?[*]C,
4048
4049 pub const empty: @This() = .{ .Length = 0, .MaximumLength = 0, .Buffer = null };
4050
4051 pub fn init(string: []const C) @This() {
4052 const len: USHORT = @intCast(@sizeOf(C) * string.len);
4053 return .{
4054 .Length = len,
4055 .MaximumLength = len,
4056 .Buffer = @constCast(string.ptr),
4057 };
4058 }
4059
4060 pub fn initZ(string: [:0]const C) @This() {
4061 const len: USHORT = @intCast(@sizeOf(C) * string.len);
4062 return .{
4063 .Length = len,
4064 .MaximumLength = len + @sizeOf(C),
4065 .Buffer = @constCast(string.ptr),
4066 };
4067 }
4068
4069 pub fn isEmpty(string: *const @This()) bool {
4070 return string.Length == 0;
4071 }
4072
4073 pub fn slice(string: *const @This()) []C {
4074 return if (string.isEmpty()) &.{} else string.Buffer.?[0..@divExact(string.Length, @sizeOf(C))];
4075 }
4076
4077 pub fn sliceZ(string: *const @This()) [:0]C {
4078 assert(string.Length + @sizeOf(C) <= string.MaximumLength);
4079 return string.Buffer.?[0..@divExact(string.Length, @sizeOf(C)) :0];
4080 }
4081 };
4082}
4083pub const ANSI_STRING = STRING(CHAR);
4084pub const UNICODE_STRING = STRING(WCHAR);
4085
4086fn Bool(comptime BackingInteger: type) type {
4087 return enum(Backing) {
4088 /// false
4089 FALSE = 0,
4090 /// true
4091 _,
4092
4093 /// This is not the only truthy value, comparisons against this value are always a bug.
4094 pub const TRUE: @This() = @fromBackingInt(@intCast(1));
4095
4096 pub const Backing = BackingInteger;
4097
4098 pub fn toBool(b: @This()) bool {
4099 return b != .FALSE;
4100 }
4101
4102 pub fn fromBool(b: bool) @This() {
4103 return @fromBackingInt(@intCast(@intFromBool(b)));
4104 }
4105 };
4106}
4107
4108pub const INVALID_HANDLE_VALUE: HANDLE = @ptrFromInt(maxInt(usize));
4109
4110pub const INVALID_FILE_ATTRIBUTES: DWORD = maxInt(DWORD);
4111
4112pub const IO_STATUS_BLOCK = extern struct {
4113 // "DUMMYUNIONNAME" expands to "u"
4114 u: extern union {
4115 Status: NTSTATUS,
4116 Pointer: ?*anyopaque,
4117 },
4118 Information: ULONG_PTR,
4119};
4120
4121pub const MAX_PATH = 260;
4122
4123pub const SECURITY_ATTRIBUTES = extern struct {
4124 nLength: DWORD,
4125 lpSecurityDescriptor: ?*anyopaque,
4126 bInheritHandle: BOOL,
4127};
4128
4129pub const STARTUPINFOW = extern struct {
4130 cb: DWORD,
4131 lpReserved: ?LPWSTR,
4132 lpDesktop: ?LPWSTR,
4133 lpTitle: ?LPWSTR,
4134 dwX: DWORD,
4135 dwY: DWORD,
4136 dwXSize: DWORD,
4137 dwYSize: DWORD,
4138 dwXCountChars: DWORD,
4139 dwYCountChars: DWORD,
4140 dwFillAttribute: DWORD,
4141 dwFlags: DWORD,
4142 wShowWindow: WORD,
4143 cbReserved2: WORD,
4144 lpReserved2: ?*BYTE,
4145 hStdInput: ?HANDLE,
4146 hStdOutput: ?HANDLE,
4147 hStdError: ?HANDLE,
4148};
4149
4150pub const STARTF_FORCEONFEEDBACK = 0x00000040;
4151pub const STARTF_FORCEOFFFEEDBACK = 0x00000080;
4152pub const STARTF_PREVENTPINNING = 0x00002000;
4153pub const STARTF_RUNFULLSCREEN = 0x00000020;
4154pub const STARTF_TITLEISAPPID = 0x00001000;
4155pub const STARTF_TITLEISLINKNAME = 0x00000800;
4156pub const STARTF_UNTRUSTEDSOURCE = 0x00008000;
4157pub const STARTF_USECOUNTCHARS = 0x00000008;
4158pub const STARTF_USEFILLATTRIBUTE = 0x00000010;
4159pub const STARTF_USEHOTKEY = 0x00000200;
4160pub const STARTF_USEPOSITION = 0x00000004;
4161pub const STARTF_USESHOWWINDOW = 0x00000001;
4162pub const STARTF_USESIZE = 0x00000002;
4163pub const STARTF_USESTDHANDLES = 0x00000100;
4164
4165pub const THREAD_START_ROUTINE = fn (LPVOID) callconv(.winapi) DWORD;
4166pub const USER_THREAD_START_ROUTINE = fn (LPVOID) callconv(.winapi) NTSTATUS;
4167
4168pub const FILETIME = extern struct {
4169 dwLowDateTime: DWORD,
4170 dwHighDateTime: DWORD,
4171};
4172
4173pub const GUID = extern struct {
4174 Data1: u32,
4175 Data2: u16,
4176 Data3: u16,
4177 Data4: [8]u8,
4178
4179 const hex_offsets: [16]u6 = .{
4180 6, 4, 2, 0,
4181 11, 9, 16, 14,
4182 19, 21, 24, 26,
4183 28, 30, 32, 34,
4184 };
4185
4186 pub fn parse(s: []const u8) GUID {
4187 assert(s[0] == '{');
4188 assert(s[37] == '}');
4189 return parseNoBraces(s[1 .. s.len - 1]) catch @panic("invalid GUID string");
4190 }
4191
4192 pub fn parseNoBraces(s: []const u8) !GUID {
4193 assert(s.len == 36);
4194 assert(s[8] == '-');
4195 assert(s[13] == '-');
4196 assert(s[18] == '-');
4197 assert(s[23] == '-');
4198 var raw1: [4]u8 = undefined;
4199 var raw2: [2]u8 = undefined;
4200 var raw3: [2]u8 = undefined;
4201 var raw4: [8]u8 = undefined;
4202 assert((try std.fmt.hexToBytes(&raw1, s[0..8])).len == raw1.len);
4203 assert((try std.fmt.hexToBytes(&raw2, s[9..13])).len == raw2.len);
4204 assert((try std.fmt.hexToBytes(&raw3, s[14..18])).len == raw3.len);
4205 assert((try std.fmt.hexToBytes(raw4[0..2], s[19..23])).len == 2);
4206 assert((try std.fmt.hexToBytes(raw4[2..8], s[24..36])).len == 6);
4207 return .{
4208 .Data1 = @byteSwap(@as(u32, @bitCast(raw1))),
4209 .Data2 = @byteSwap(@as(u16, @bitCast(raw2))),
4210 .Data3 = @byteSwap(@as(u16, @bitCast(raw3))),
4211 .Data4 = raw4,
4212 };
4213 }
4214
4215 pub fn format(self: GUID, w: *std.Io.Writer) std.Io.Writer.Error!void {
4216 return w.print("{{{x:0>8}-{x:0>4}-{x:0>4}-{x}-{x}}}", .{
4217 self.Data1,
4218 self.Data2,
4219 self.Data3,
4220 self.Data4[0..2],
4221 self.Data4[2..8],
4222 });
4223 }
4224
4225 test parse {
4226 const expected: GUID = .{
4227 .Data1 = 0x01234567,
4228 .Data2 = 0x89ab,
4229 .Data3 = 0xef10,
4230 .Data4 = "\x32\x54\x76\x98\xba\xdc\xfe\x91".*,
4231 };
4232 try std.testing.expectEqual(expected, GUID.parse("{01234567-89AB-EF10-3254-7698badcfe91}"));
4233 }
4234
4235 test format {
4236 const guid0: GUID = .{ .Data1 = 1, .Data2 = 1, .Data3 = 1, .Data4 = .{ 0, 1, 0, 0, 0, 0, 0, 1 } };
4237 try std.testing.expectFmt("{00000001-0001-0001-0001-000000000001}", "{f}", .{guid0});
4238
4239 const guid1: GUID = .parse("{01234567-89AB-EF10-3254-7698badcfe91}");
4240 try std.testing.expectFmt("{01234567-89ab-ef10-3254-7698badcfe91}", "{f}", .{guid1});
4241 }
4242};
4243
4244test {
4245 _ = GUID;
4246}
4247
4248pub const COORD = extern struct {
4249 X: SHORT,
4250 Y: SHORT,
4251};
4252
4253pub const TLS_OUT_OF_INDEXES = 4294967295;
4254pub const IMAGE_TLS_DIRECTORY = extern struct {
4255 StartAddressOfRawData: usize,
4256 EndAddressOfRawData: usize,
4257 AddressOfIndex: usize,
4258 AddressOfCallBacks: usize,
4259 SizeOfZeroFill: u32,
4260 Characteristics: u32,
4261};
4262pub const IMAGE_TLS_DIRECTORY64 = IMAGE_TLS_DIRECTORY;
4263pub const IMAGE_TLS_DIRECTORY32 = IMAGE_TLS_DIRECTORY;
4264
4265pub const PIMAGE_TLS_CALLBACK = ?*const fn (PVOID, DWORD, PVOID) callconv(.winapi) void;
4266
4267pub const REGSAM = ACCESS_MASK;
4268pub const LSTATUS = LONG;
4269
4270pub const HKEY = *opaque {};
4271
4272pub const HKEY_CLASSES_ROOT: HKEY = @ptrFromInt(0x80000000);
4273pub const HKEY_CURRENT_USER: HKEY = @ptrFromInt(0x80000001);
4274pub const HKEY_LOCAL_MACHINE: HKEY = @ptrFromInt(0x80000002);
4275pub const HKEY_USERS: HKEY = @ptrFromInt(0x80000003);
4276pub const HKEY_PERFORMANCE_DATA: HKEY = @ptrFromInt(0x80000004);
4277pub const HKEY_PERFORMANCE_TEXT: HKEY = @ptrFromInt(0x80000050);
4278pub const HKEY_PERFORMANCE_NLSTEXT: HKEY = @ptrFromInt(0x80000060);
4279pub const HKEY_CURRENT_CONFIG: HKEY = @ptrFromInt(0x80000005);
4280pub const HKEY_DYN_DATA: HKEY = @ptrFromInt(0x80000006);
4281pub const HKEY_CURRENT_USER_LOCAL_SETTINGS: HKEY = @ptrFromInt(0x80000007);
4282
4283pub const RTL_QUERY_REGISTRY_TABLE = extern struct {
4284 QueryRoutine: RTL_QUERY_REGISTRY_ROUTINE,
4285 Flags: ULONG,
4286 Name: ?PWSTR,
4287 EntryContext: ?*anyopaque,
4288 DefaultType: REG.ValueType,
4289 DefaultData: ?*anyopaque,
4290 DefaultLength: ULONG,
4291};
4292
4293pub const RTL_QUERY_REGISTRY_ROUTINE = ?*const fn (
4294 PWSTR,
4295 ULONG,
4296 ?*anyopaque,
4297 ULONG,
4298 ?*anyopaque,
4299 ?*anyopaque,
4300) callconv(.winapi) NTSTATUS;
4301
4302/// Path is a full path
4303pub const RTL_REGISTRY_ABSOLUTE = 0;
4304/// \Registry\Machine\System\CurrentControlSet\Services
4305pub const RTL_REGISTRY_SERVICES = 1;
4306/// \Registry\Machine\System\CurrentControlSet\Control
4307pub const RTL_REGISTRY_CONTROL = 2;
4308/// \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion
4309pub const RTL_REGISTRY_WINDOWS_NT = 3;
4310/// \Registry\Machine\Hardware\DeviceMap
4311pub const RTL_REGISTRY_DEVICEMAP = 4;
4312/// \Registry\User\CurrentUser
4313pub const RTL_REGISTRY_USER = 5;
4314pub const RTL_REGISTRY_MAXIMUM = 6;
4315
4316/// Low order bits are registry handle
4317pub const RTL_REGISTRY_HANDLE = 0x40000000;
4318/// Indicates the key node is optional
4319pub const RTL_REGISTRY_OPTIONAL = 0x80000000;
4320
4321/// Name is a subkey and remainder of table or until next subkey are value
4322/// names for that subkey to look at.
4323pub const RTL_QUERY_REGISTRY_SUBKEY = 0x00000001;
4324
4325/// Reset current key to original key for this and all following table entries.
4326pub const RTL_QUERY_REGISTRY_TOPKEY = 0x00000002;
4327
4328/// Fail if no match found for this table entry.
4329pub const RTL_QUERY_REGISTRY_REQUIRED = 0x00000004;
4330
4331/// Used to mark a table entry that has no value name, just wants a call out, not
4332/// an enumeration of all values.
4333pub const RTL_QUERY_REGISTRY_NOVALUE = 0x00000008;
4334
4335/// Used to suppress the expansion of REG_MULTI_SZ into multiple callouts or
4336/// to prevent the expansion of environment variable values in REG_EXPAND_SZ.
4337pub const RTL_QUERY_REGISTRY_NOEXPAND = 0x00000010;
4338
4339/// QueryRoutine field ignored. EntryContext field points to location to store value.
4340/// For null terminated strings, EntryContext points to UNICODE_STRING structure that
4341/// that describes maximum size of buffer. If .Buffer field is NULL then a buffer is
4342/// allocated.
4343pub const RTL_QUERY_REGISTRY_DIRECT = 0x00000020;
4344
4345/// Used to delete value keys after they are queried.
4346pub const RTL_QUERY_REGISTRY_DELETE = 0x00000040;
4347
4348/// Use this flag with the RTL_QUERY_REGISTRY_DIRECT flag to verify that the REG_XXX type
4349/// of the stored registry value matches the type expected by the caller.
4350/// If the types do not match, the call fails.
4351pub const RTL_QUERY_REGISTRY_TYPECHECK = 0x00000100;
4352
4353/// REG_ is a crowded namespace with a lot of overlapping and unrelated
4354/// defines in the Windows headers, so instead of strictly following the
4355/// Windows headers names, extra namespaces are added here for clarity.
4356pub const REG = struct {
4357 pub const ValueType = enum(ULONG) {
4358 /// No value type
4359 NONE = 0,
4360 /// Unicode nul terminated string
4361 SZ = 1,
4362 /// Unicode nul terminated string (with environment variable references)
4363 EXPAND_SZ = 2,
4364 /// Free form binary
4365 BINARY = 3,
4366 /// 32-bit number
4367 DWORD = 4,
4368 /// 32-bit number
4369 DWORD_BIG_ENDIAN = 5,
4370 /// Symbolic Link (unicode)
4371 LINK = 6,
4372 /// Multiple Unicode strings
4373 MULTI_SZ = 7,
4374 /// Resource list in the resource map
4375 RESOURCE_LIST = 8,
4376 /// Resource list in the hardware description
4377 FULL_RESOURCE_DESCRIPTOR = 9,
4378 RESOURCE_REQUIREMENTS_LIST = 10,
4379 /// 64-bit number
4380 QWORD = 11,
4381 _,
4382
4383 /// 32-bit number (same as REG_DWORD)
4384 pub const DWORD_LITTLE_ENDIAN: ValueType = .DWORD;
4385 /// 64-bit number (same as REG_QWORD)
4386 pub const QWORD_LITTLE_ENDIAN: ValueType = .QWORD;
4387 };
4388
4389 /// Used with NtOpenKeyEx, maybe others
4390 pub const OpenOptions = packed struct(ULONG) {
4391 Reserved0: u2 = 0,
4392 /// Open for backup or restore
4393 /// special access rules privilege required
4394 BACKUP_RESTORE: bool = false,
4395 /// Open symbolic link
4396 OPEN_LINK: bool = false,
4397 Reserved3: u28 = 0,
4398 };
4399
4400 /// Used with NtLoadKeyEx, maybe others
4401 pub const LoadOptions = packed struct(ULONG) {
4402 /// Restore whole hive volatile
4403 WHOLE_HIVE_VOLATILE: bool = false,
4404 /// Unwind changes to last flush
4405 REFRESH_HIVE: bool = false,
4406 /// Never lazy flush this hive
4407 NO_LAZY_FLUSH: bool = false,
4408 /// Force the restore process even when we have open handles on subkeys
4409 FORCE_RESTORE: bool = false,
4410 /// Loads the hive visible to the calling process
4411 APP_HIVE: bool = false,
4412 /// Hive cannot be mounted by any other process while in use
4413 PROCESS_PRIVATE: bool = false,
4414 /// Starts Hive Journal
4415 START_JOURNAL: bool = false,
4416 /// Grow hive file in exact 4k increments
4417 HIVE_EXACT_FILE_GROWTH: bool = false,
4418 /// No RM is started for this hive (no transactions)
4419 HIVE_NO_RM: bool = false,
4420 /// Legacy single logging is used for this hive
4421 HIVE_SINGLE_LOG: bool = false,
4422 /// This hive might be used by the OS loader
4423 BOOT_HIVE: bool = false,
4424 /// Load the hive and return a handle to its root kcb
4425 LOAD_HIVE_OPEN_HANDLE: bool = false,
4426 /// Flush changes to primary hive file size as part of all flushes
4427 FLUSH_HIVE_FILE_GROWTH: bool = false,
4428 /// Open a hive's files in read-only mode
4429 /// The same flag is used for REG_APP_HIVE_OPEN_READ_ONLY:
4430 /// Open an app hive's files in read-only mode (if the hive was not previously loaded).
4431 OPEN_READ_ONLY: bool = false,
4432 /// Load the hive, but don't allow any modification of it
4433 IMMUTABLE: bool = false,
4434 /// Do not fall back to impersonating the caller if hive file access fails
4435 NO_IMPERSONATION_FALLBACK: bool = false,
4436 Reserved16: u16 = 0,
4437 };
4438};
4439
4440pub const KEY = struct {
4441 pub const VALUE = struct {
4442 /// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ne-wdm-_key_value_information_class
4443 pub const INFORMATION_CLASS = enum(c_int) {
4444 Basic = 0,
4445 Full = 1,
4446 Partial = 2,
4447 FullAlign64 = 3,
4448 PartialAlign64 = 4,
4449 Layer = 5,
4450 _,
4451
4452 pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".field_names.len;
4453 };
4454
4455 pub const PARTIAL_INFORMATION = extern struct {
4456 TitleIndex: ULONG,
4457 Type: REG.ValueType,
4458 DataLength: ULONG,
4459 Data: [0]UCHAR,
4460
4461 pub fn data(info: *const PARTIAL_INFORMATION) []const UCHAR {
4462 const ptr: [*]const UCHAR = @ptrCast(&info.Data);
4463 return ptr[0..info.DataLength];
4464 }
4465 };
4466 };
4467};
4468
4469pub const ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4;
4470pub const DISABLE_NEWLINE_AUTO_RETURN = 0x8;
4471
4472pub const FOREGROUND_BLUE = 0x0001;
4473pub const FOREGROUND_GREEN = 0x0002;
4474pub const FOREGROUND_RED = 0x0004;
4475pub const FOREGROUND_INTENSITY = 0x0008;
4476pub const BACKGROUND_BLUE = 0x0010;
4477pub const BACKGROUND_GREEN = 0x0020;
4478pub const BACKGROUND_RED = 0x0040;
4479pub const BACKGROUND_INTENSITY = 0x0080;
4480
4481pub const LIST_ENTRY = extern struct {
4482 Flink: *LIST_ENTRY,
4483 Blink: *LIST_ENTRY,
4484};
4485
4486pub const RTL_CRITICAL_SECTION_DEBUG = extern struct {
4487 Type: WORD,
4488 CreatorBackTraceIndex: WORD,
4489 CriticalSection: *RTL_CRITICAL_SECTION,
4490 ProcessLocksList: LIST_ENTRY,
4491 EntryCount: DWORD,
4492 ContentionCount: DWORD,
4493 Flags: DWORD,
4494 CreatorBackTraceIndexHigh: WORD,
4495 SpareWORD: WORD,
4496};
4497
4498pub const RTL_CRITICAL_SECTION = extern struct {
4499 DebugInfo: *RTL_CRITICAL_SECTION_DEBUG,
4500 LockCount: LONG,
4501 RecursionCount: LONG,
4502 OwningThread: HANDLE,
4503 LockSemaphore: HANDLE,
4504 SpinCount: ULONG_PTR,
4505};
4506
4507pub const CRITICAL_SECTION = RTL_CRITICAL_SECTION;
4508pub const INIT_ONCE = RTL_RUN_ONCE;
4509pub const INIT_ONCE_STATIC_INIT = RTL_RUN_ONCE_INIT;
4510pub const INIT_ONCE_FN = *const fn (InitOnce: *INIT_ONCE, Parameter: ?*anyopaque, Context: ?*anyopaque) callconv(.winapi) BOOL;
4511
4512pub const RTL_RUN_ONCE = extern struct {
4513 Ptr: ?*anyopaque,
4514};
4515
4516pub const RTL_RUN_ONCE_INIT = RTL_RUN_ONCE{ .Ptr = null };
4517
4518/// > The maximum path of 32,767 characters is approximate, because the "\\?\"
4519/// > prefix may be expanded to a longer string by the system at run time, and
4520/// > this expansion applies to the total length.
4521/// from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation
4522pub const PATH_MAX_WIDE = 32767;
4523
4524/// > [Each file name component can be] up to the value returned in the
4525/// > lpMaximumComponentLength parameter of the GetVolumeInformation function
4526/// > (this value is commonly 255 characters)
4527/// from https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
4528///
4529/// > The value that is stored in the variable that *lpMaximumComponentLength points to is
4530/// > used to indicate that a specified file system supports long names. For example, for
4531/// > a FAT file system that supports long names, the function stores the value 255, rather
4532/// > than the previous 8.3 indicator. Long names can also be supported on systems that use
4533/// > the NTFS file system.
4534/// from https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationw
4535///
4536/// The assumption being made here is that while lpMaximumComponentLength may vary, it will never
4537/// be larger than 255.
4538///
4539/// TODO: More verification of this assumption.
4540pub const NAME_MAX = 255;
4541
4542pub const EXCEPTION_DATATYPE_MISALIGNMENT = 0x80000002;
4543pub const EXCEPTION_ACCESS_VIOLATION = 0xc0000005;
4544pub const EXCEPTION_ILLEGAL_INSTRUCTION = 0xc000001d;
4545pub const EXCEPTION_STACK_OVERFLOW = 0xc00000fd;
4546pub const EXCEPTION_CONTINUE_SEARCH = 0;
4547
4548pub const EXCEPTION_RECORD = extern struct {
4549 ExceptionCode: u32,
4550 ExceptionFlags: u32,
4551 ExceptionRecord: *EXCEPTION_RECORD,
4552 ExceptionAddress: *anyopaque,
4553 NumberParameters: u32,
4554 ExceptionInformation: [15]usize,
4555};
4556
4557pub const FLOATING_SAVE_AREA = switch (native_arch) {
4558 .x86 => extern struct {
4559 ControlWord: DWORD,
4560 StatusWord: DWORD,
4561 TagWord: DWORD,
4562 ErrorOffset: DWORD,
4563 ErrorSelector: DWORD,
4564 DataOffset: DWORD,
4565 DataSelector: DWORD,
4566 RegisterArea: [80]BYTE,
4567 Cr0NpxState: DWORD,
4568 },
4569 else => @compileError("FLOATING_SAVE_AREA only defined on x86"),
4570};
4571
4572pub const M128A = switch (native_arch) {
4573 .x86_64 => extern struct {
4574 Low: ULONGLONG,
4575 High: LONGLONG,
4576 },
4577 else => @compileError("M128A only defined on x86_64"),
4578};
4579
4580pub const XMM_SAVE_AREA32 = switch (native_arch) {
4581 .x86_64 => extern struct {
4582 ControlWord: WORD,
4583 StatusWord: WORD,
4584 TagWord: BYTE,
4585 Reserved1: BYTE,
4586 ErrorOpcode: WORD,
4587 ErrorOffset: DWORD,
4588 ErrorSelector: WORD,
4589 Reserved2: WORD,
4590 DataOffset: DWORD,
4591 DataSelector: WORD,
4592 Reserved3: WORD,
4593 MxCsr: DWORD,
4594 MxCsr_Mask: DWORD,
4595 FloatRegisters: [8]M128A,
4596 XmmRegisters: [16]M128A,
4597 Reserved4: [96]BYTE,
4598 },
4599 else => @compileError("XMM_SAVE_AREA32 only defined on x86_64"),
4600};
4601
4602pub const NEON128 = switch (native_arch) {
4603 .thumb => extern struct {
4604 Low: ULONGLONG,
4605 High: LONGLONG,
4606 },
4607 .aarch64 => extern union {
4608 DUMMYSTRUCTNAME: extern struct {
4609 Low: ULONGLONG,
4610 High: LONGLONG,
4611 },
4612 D: [2]f64,
4613 S: [4]f32,
4614 H: [8]WORD,
4615 B: [16]BYTE,
4616 },
4617 else => @compileError("NEON128 only defined on aarch64"),
4618};
4619
4620pub const CONTEXT = switch (native_arch) {
4621 .x86 => extern struct {
4622 ContextFlags: DWORD,
4623 Dr0: DWORD,
4624 Dr1: DWORD,
4625 Dr2: DWORD,
4626 Dr3: DWORD,
4627 Dr6: DWORD,
4628 Dr7: DWORD,
4629 FloatSave: FLOATING_SAVE_AREA,
4630 SegGs: DWORD,
4631 SegFs: DWORD,
4632 SegEs: DWORD,
4633 SegDs: DWORD,
4634 Edi: DWORD,
4635 Esi: DWORD,
4636 Ebx: DWORD,
4637 Edx: DWORD,
4638 Ecx: DWORD,
4639 Eax: DWORD,
4640 Ebp: DWORD,
4641 Eip: DWORD,
4642 SegCs: DWORD,
4643 EFlags: DWORD,
4644 Esp: DWORD,
4645 SegSs: DWORD,
4646 ExtendedRegisters: [512]BYTE,
4647
4648 pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize, sp: usize } {
4649 return .{ .bp = ctx.Ebp, .ip = ctx.Eip, .sp = ctx.Esp };
4650 }
4651 },
4652 .x86_64 => extern struct {
4653 P1Home: DWORD64 align(16),
4654 P2Home: DWORD64,
4655 P3Home: DWORD64,
4656 P4Home: DWORD64,
4657 P5Home: DWORD64,
4658 P6Home: DWORD64,
4659 ContextFlags: DWORD,
4660 MxCsr: DWORD,
4661 SegCs: WORD,
4662 SegDs: WORD,
4663 SegEs: WORD,
4664 SegFs: WORD,
4665 SegGs: WORD,
4666 SegSs: WORD,
4667 EFlags: DWORD,
4668 Dr0: DWORD64,
4669 Dr1: DWORD64,
4670 Dr2: DWORD64,
4671 Dr3: DWORD64,
4672 Dr6: DWORD64,
4673 Dr7: DWORD64,
4674 Rax: DWORD64,
4675 Rcx: DWORD64,
4676 Rdx: DWORD64,
4677 Rbx: DWORD64,
4678 Rsp: DWORD64,
4679 Rbp: DWORD64,
4680 Rsi: DWORD64,
4681 Rdi: DWORD64,
4682 R8: DWORD64,
4683 R9: DWORD64,
4684 R10: DWORD64,
4685 R11: DWORD64,
4686 R12: DWORD64,
4687 R13: DWORD64,
4688 R14: DWORD64,
4689 R15: DWORD64,
4690 Rip: DWORD64,
4691 DUMMYUNIONNAME: extern union {
4692 FltSave: XMM_SAVE_AREA32,
4693 FloatSave: XMM_SAVE_AREA32,
4694 DUMMYSTRUCTNAME: extern struct {
4695 Header: [2]M128A,
4696 Legacy: [8]M128A,
4697 Xmm0: M128A,
4698 Xmm1: M128A,
4699 Xmm2: M128A,
4700 Xmm3: M128A,
4701 Xmm4: M128A,
4702 Xmm5: M128A,
4703 Xmm6: M128A,
4704 Xmm7: M128A,
4705 Xmm8: M128A,
4706 Xmm9: M128A,
4707 Xmm10: M128A,
4708 Xmm11: M128A,
4709 Xmm12: M128A,
4710 Xmm13: M128A,
4711 Xmm14: M128A,
4712 Xmm15: M128A,
4713 },
4714 },
4715 VectorRegister: [26]M128A,
4716 VectorControl: DWORD64,
4717 DebugControl: DWORD64,
4718 LastBranchToRip: DWORD64,
4719 LastBranchFromRip: DWORD64,
4720 LastExceptionToRip: DWORD64,
4721 LastExceptionFromRip: DWORD64,
4722
4723 pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize, sp: usize } {
4724 return .{ .bp = ctx.Rbp, .ip = ctx.Rip, .sp = ctx.Rsp };
4725 }
4726
4727 pub fn setIp(ctx: *CONTEXT, ip: usize) void {
4728 ctx.Rip = ip;
4729 }
4730
4731 pub fn setSp(ctx: *CONTEXT, sp: usize) void {
4732 ctx.Rsp = sp;
4733 }
4734 },
4735 .thumb => extern struct {
4736 ContextFlags: ULONG,
4737 R0: ULONG,
4738 R1: ULONG,
4739 R2: ULONG,
4740 R3: ULONG,
4741 R4: ULONG,
4742 R5: ULONG,
4743 R6: ULONG,
4744 R7: ULONG,
4745 R8: ULONG,
4746 R9: ULONG,
4747 R10: ULONG,
4748 R11: ULONG,
4749 R12: ULONG,
4750 Sp: ULONG,
4751 Lr: ULONG,
4752 Pc: ULONG,
4753 Cpsr: ULONG,
4754 Fpcsr: ULONG,
4755 Padding: ULONG,
4756 DUMMYUNIONNAME: extern union {
4757 Q: [16]NEON128,
4758 D: [32]ULONGLONG,
4759 S: [32]ULONG,
4760 },
4761 Bvr: [8]ULONG,
4762 Bcr: [8]ULONG,
4763 Wvr: [1]ULONG,
4764 Wcr: [1]ULONG,
4765 Padding2: [2]ULONG,
4766
4767 pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize, sp: usize } {
4768 return .{
4769 .bp = ctx.DUMMYUNIONNAME.S[11],
4770 .ip = ctx.Pc,
4771 .sp = ctx.Sp,
4772 };
4773 }
4774
4775 pub fn setIp(ctx: *CONTEXT, ip: usize) void {
4776 ctx.Pc = ip;
4777 }
4778
4779 pub fn setSp(ctx: *CONTEXT, sp: usize) void {
4780 ctx.Sp = sp;
4781 }
4782 },
4783 .aarch64 => extern struct {
4784 ContextFlags: ULONG align(16),
4785 Cpsr: ULONG,
4786 DUMMYUNIONNAME: extern union {
4787 DUMMYSTRUCTNAME: extern struct {
4788 X0: DWORD64,
4789 X1: DWORD64,
4790 X2: DWORD64,
4791 X3: DWORD64,
4792 X4: DWORD64,
4793 X5: DWORD64,
4794 X6: DWORD64,
4795 X7: DWORD64,
4796 X8: DWORD64,
4797 X9: DWORD64,
4798 X10: DWORD64,
4799 X11: DWORD64,
4800 X12: DWORD64,
4801 X13: DWORD64,
4802 X14: DWORD64,
4803 X15: DWORD64,
4804 X16: DWORD64,
4805 X17: DWORD64,
4806 X18: DWORD64,
4807 X19: DWORD64,
4808 X20: DWORD64,
4809 X21: DWORD64,
4810 X22: DWORD64,
4811 X23: DWORD64,
4812 X24: DWORD64,
4813 X25: DWORD64,
4814 X26: DWORD64,
4815 X27: DWORD64,
4816 X28: DWORD64,
4817 Fp: DWORD64,
4818 Lr: DWORD64,
4819 },
4820 X: [31]DWORD64,
4821 },
4822 Sp: DWORD64,
4823 Pc: DWORD64,
4824 V: [32]NEON128,
4825 Fpcr: DWORD,
4826 Fpsr: DWORD,
4827 Bcr: [8]DWORD,
4828 Bvr: [8]DWORD64,
4829 Wcr: [2]DWORD,
4830 Wvr: [2]DWORD64,
4831
4832 pub fn getRegs(ctx: *const CONTEXT) struct { bp: usize, ip: usize, sp: usize } {
4833 return .{
4834 .bp = ctx.DUMMYUNIONNAME.DUMMYSTRUCTNAME.Fp,
4835 .ip = ctx.Pc,
4836 .sp = ctx.Sp,
4837 };
4838 }
4839
4840 pub fn setIp(ctx: *CONTEXT, ip: usize) void {
4841 ctx.Pc = ip;
4842 }
4843
4844 pub fn setSp(ctx: *CONTEXT, sp: usize) void {
4845 ctx.Sp = sp;
4846 }
4847 },
4848 else => @compileError("CONTEXT is not defined for this architecture"),
4849};
4850
4851pub const RUNTIME_FUNCTION = switch (native_arch) {
4852 .x86_64 => extern struct {
4853 BeginAddress: DWORD,
4854 EndAddress: DWORD,
4855 UnwindData: DWORD,
4856 },
4857 .thumb => extern struct {
4858 BeginAddress: DWORD,
4859 DUMMYUNIONNAME: extern union {
4860 UnwindData: DWORD,
4861 DUMMYSTRUCTNAME: packed struct(u32) {
4862 Flag: u2,
4863 FunctionLength: u11,
4864 Ret: u2,
4865 H: u1,
4866 Reg: u3,
4867 R: u1,
4868 L: u1,
4869 C: u1,
4870 StackAdjust: u10,
4871 },
4872 },
4873 },
4874 .aarch64 => extern struct {
4875 BeginAddress: DWORD,
4876 DUMMYUNIONNAME: extern union {
4877 UnwindData: DWORD,
4878 DUMMYSTRUCTNAME: packed struct(u32) {
4879 Flag: u2,
4880 FunctionLength: u11,
4881 RegF: u3,
4882 RegI: u4,
4883 H: u1,
4884 CR: u2,
4885 FrameSize: u9,
4886 },
4887 },
4888 },
4889 else => @compileError("RUNTIME_FUNCTION is not defined for this architecture"),
4890};
4891
4892pub const KNONVOLATILE_CONTEXT_POINTERS = switch (native_arch) {
4893 .x86_64 => extern struct {
4894 FloatingContext: [16]?*M128A,
4895 IntegerContext: [16]?*ULONG64,
4896 },
4897 .thumb => extern struct {
4898 R4: ?*DWORD,
4899 R5: ?*DWORD,
4900 R6: ?*DWORD,
4901 R7: ?*DWORD,
4902 R8: ?*DWORD,
4903 R9: ?*DWORD,
4904 R10: ?*DWORD,
4905 R11: ?*DWORD,
4906 Lr: ?*DWORD,
4907 D8: ?*ULONGLONG,
4908 D9: ?*ULONGLONG,
4909 D10: ?*ULONGLONG,
4910 D11: ?*ULONGLONG,
4911 D12: ?*ULONGLONG,
4912 D13: ?*ULONGLONG,
4913 D14: ?*ULONGLONG,
4914 D15: ?*ULONGLONG,
4915 },
4916 .aarch64 => extern struct {
4917 X19: ?*DWORD64,
4918 X20: ?*DWORD64,
4919 X21: ?*DWORD64,
4920 X22: ?*DWORD64,
4921 X23: ?*DWORD64,
4922 X24: ?*DWORD64,
4923 X25: ?*DWORD64,
4924 X26: ?*DWORD64,
4925 X27: ?*DWORD64,
4926 X28: ?*DWORD64,
4927 Fp: ?*DWORD64,
4928 Lr: ?*DWORD64,
4929 D8: ?*DWORD64,
4930 D9: ?*DWORD64,
4931 D10: ?*DWORD64,
4932 D11: ?*DWORD64,
4933 D12: ?*DWORD64,
4934 D13: ?*DWORD64,
4935 D14: ?*DWORD64,
4936 D15: ?*DWORD64,
4937 },
4938 else => @compileError("KNONVOLATILE_CONTEXT_POINTERS is not defined for this architecture"),
4939};
4940
4941pub const EXCEPTION_POINTERS = extern struct {
4942 ExceptionRecord: *EXCEPTION_RECORD,
4943 ContextRecord: *CONTEXT,
4944};
4945
4946pub const VECTORED_EXCEPTION_HANDLER = *const fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(.winapi) c_long;
4947
4948pub const EXCEPTION_DISPOSITION = i32;
4949pub const EXCEPTION_ROUTINE = *const fn (
4950 ExceptionRecord: ?*EXCEPTION_RECORD,
4951 EstablisherFrame: PVOID,
4952 ContextRecord: *CONTEXT,
4953 DispatcherContext: PVOID,
4954) callconv(.winapi) EXCEPTION_DISPOSITION;
4955
4956pub const UNWIND_HISTORY_TABLE_SIZE = 12;
4957pub const UNWIND_HISTORY_TABLE_ENTRY = extern struct {
4958 ImageBase: ULONG64,
4959 FunctionEntry: *RUNTIME_FUNCTION,
4960};
4961
4962pub const UNWIND_HISTORY_TABLE = extern struct {
4963 Count: ULONG,
4964 LocalHint: BYTE,
4965 GlobalHint: BYTE,
4966 Search: BYTE,
4967 Once: BYTE,
4968 LowAddress: ULONG64,
4969 HighAddress: ULONG64,
4970 Entry: [UNWIND_HISTORY_TABLE_SIZE]UNWIND_HISTORY_TABLE_ENTRY,
4971};
4972
4973pub const UNW_FLAG_NHANDLER = 0x0;
4974pub const UNW_FLAG_EHANDLER = 0x1;
4975pub const UNW_FLAG_UHANDLER = 0x2;
4976pub const UNW_FLAG_CHAININFO = 0x4;
4977
4978pub const ACTIVATION_CONTEXT_DATA = opaque {};
4979pub const ASSEMBLY_STORAGE_MAP = opaque {};
4980pub const FLS_CALLBACK_INFO = opaque {};
4981pub const RTL_BITMAP = opaque {};
4982pub const KAFFINITY = usize;
4983pub const KPRIORITY = i32;
4984
4985pub const CLIENT_ID = extern struct {
4986 UniqueProcess: ?HANDLE,
4987 UniqueThread: ?HANDLE,
4988};
4989
4990pub const TEB = extern struct {
4991 NtTib: NT_TIB,
4992 EnvironmentPointer: PVOID,
4993 ClientId: CLIENT_ID,
4994 ActiveRpcHandle: PVOID,
4995 ThreadLocalStoragePointer: PVOID,
4996 ProcessEnvironmentBlock: *PEB,
4997 LastErrorValue: Win32Error,
4998 Reserved2: [399 * @sizeOf(PVOID) - @sizeOf(ULONG)]u8,
4999 Reserved3: [1952]u8,
5000 TlsSlots: [64]PVOID,
5001 Reserved4: [8]u8,
5002 Reserved5: [26]PVOID,
5003 ReservedForOle: PVOID,
5004 Reserved6: [4]PVOID,
5005 TlsExpansionSlots: PVOID,
5006};
5007
5008comptime {
5009 // XXX: Without this check we cannot use `std.Io.Writer` on 16-bit platforms. `std.mem.print` will hit the unreachable in `PEB.GdiHandleBuffer` without this guard.
5010 if (builtin.os.tag == .windows) {
5011 // Offsets taken from WinDbg info and Geoff Chappell[1] (RIP)
5012 // [1]: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/pebteb/teb/index.htm
5013 assert(@offsetOf(TEB, "NtTib") == 0x00);
5014 if (@sizeOf(usize) == 4) {
5015 assert(@offsetOf(TEB, "EnvironmentPointer") == 0x1C);
5016 assert(@offsetOf(TEB, "ClientId") == 0x20);
5017 assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x28);
5018 assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x2C);
5019 assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x30);
5020 assert(@offsetOf(TEB, "LastErrorValue") == 0x34);
5021 assert(@offsetOf(TEB, "TlsSlots") == 0xe10);
5022 } else if (@sizeOf(usize) == 8) {
5023 assert(@offsetOf(TEB, "EnvironmentPointer") == 0x38);
5024 assert(@offsetOf(TEB, "ClientId") == 0x40);
5025 assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x50);
5026 assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x58);
5027 assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x60);
5028 assert(@offsetOf(TEB, "LastErrorValue") == 0x68);
5029 assert(@offsetOf(TEB, "TlsSlots") == 0x1480);
5030 }
5031 }
5032}
5033
5034pub const EXCEPTION_REGISTRATION_RECORD = extern struct {
5035 Next: ?*EXCEPTION_REGISTRATION_RECORD,
5036 Handler: ?*EXCEPTION_DISPOSITION,
5037};
5038
5039pub const NT_TIB = extern struct {
5040 ExceptionList: ?*EXCEPTION_REGISTRATION_RECORD,
5041 StackBase: PVOID,
5042 StackLimit: PVOID,
5043 SubSystemTib: PVOID,
5044 DUMMYUNIONNAME: extern union { FiberData: PVOID, Version: DWORD },
5045 ArbitraryUserPointer: PVOID,
5046 Self: ?*@This(),
5047};
5048
5049/// Process Environment Block
5050/// Microsoft documentation of this is incomplete, the fields here are taken from various resources including:
5051/// - https://github.com/wine-mirror/wine/blob/1aff1e6a370ee8c0213a0fd4b220d121da8527aa/include/winternl.h#L269
5052/// - https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/index.htm
5053pub const PEB = extern struct {
5054 // Versions: All
5055 InheritedAddressSpace: BOOLEAN,
5056
5057 // Versions: 3.51+
5058 ReadImageFileExecOptions: BOOLEAN,
5059 BeingDebugged: BOOLEAN,
5060
5061 // Versions: 5.2+ (previously was padding)
5062 BitField: UCHAR,
5063
5064 // Versions: all
5065 Mutant: HANDLE,
5066 ImageBaseAddress: HMODULE,
5067 Ldr: *PEB_LDR_DATA,
5068 ProcessParameters: *RTL_USER_PROCESS_PARAMETERS,
5069 SubSystemData: PVOID,
5070 ProcessHeap: ?*HEAP,
5071
5072 // Versions: 5.1+
5073 FastPebLock: *RTL_CRITICAL_SECTION,
5074
5075 // Versions: 5.2+
5076 AtlThunkSListPtr: PVOID,
5077 IFEOKey: PVOID,
5078
5079 // Versions: 6.0+
5080
5081 /// https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/crossprocessflags.htm
5082 CrossProcessFlags: ULONG,
5083
5084 // Versions: 6.0+
5085 union1: extern union {
5086 KernelCallbackTable: PVOID,
5087 UserSharedInfoPtr: PVOID,
5088 },
5089
5090 // Versions: 5.1+
5091 SystemReserved: ULONG,
5092
5093 // Versions: 5.1, (not 5.2, not 6.0), 6.1+
5094 AtlThunkSListPtr32: ULONG,
5095
5096 // Versions: 6.1+
5097 ApiSetMap: PVOID,
5098
5099 // Versions: all
5100 TlsExpansionCounter: ULONG,
5101 // note: there is padding here on 64 bit
5102 TlsBitmap: *RTL_BITMAP,
5103 TlsBitmapBits: [2]ULONG,
5104 /// Our base address of the memory region shared with the CSR server.
5105 ReadOnlySharedMemoryBase: PVOID,
5106
5107 // Versions: 1703+
5108 SharedData: PVOID,
5109
5110 // Versions: all
5111 ReadOnlyStaticServerData: *UnknownStaticServerDataIndirection,
5112 AnsiCodePageData: PVOID,
5113 OemCodePageData: PVOID,
5114 UnicodeCaseTableData: PVOID,
5115
5116 // Versions: 3.51+
5117 NumberOfProcessors: ULONG,
5118 NtGlobalFlag: ULONG,
5119
5120 // Versions: all
5121 CriticalSectionTimeout: LARGE_INTEGER,
5122
5123 // End of Original PEB size
5124
5125 // Fields appended in 3.51:
5126 HeapSegmentReserve: ULONG_PTR,
5127 HeapSegmentCommit: ULONG_PTR,
5128 HeapDeCommitTotalFreeThreshold: ULONG_PTR,
5129 HeapDeCommitFreeBlockThreshold: ULONG_PTR,
5130 NumberOfHeaps: ULONG,
5131 MaximumNumberOfHeaps: ULONG,
5132 ProcessHeaps: *PVOID,
5133
5134 // Fields appended in 4.0:
5135 GdiSharedHandleTable: PVOID,
5136 ProcessStarterHelper: PVOID,
5137 GdiDCAttributeList: ULONG,
5138 // note: there is padding here on 64 bit
5139 LoaderLock: *RTL_CRITICAL_SECTION,
5140 OSMajorVersion: ULONG,
5141 OSMinorVersion: ULONG,
5142 OSBuildNumber: USHORT,
5143 OSCSDVersion: USHORT,
5144 OSPlatformId: ULONG,
5145 ImageSubSystem: ULONG,
5146 ImageSubSystemMajorVersion: ULONG,
5147 ImageSubSystemMinorVersion: ULONG,
5148 // note: there is padding here on 64 bit
5149 ActiveProcessAffinityMask: KAFFINITY,
5150 GdiHandleBuffer: [
5151 switch (@sizeOf(usize)) {
5152 4 => 0x22,
5153 8 => 0x3C,
5154 else => unreachable,
5155 }
5156 ]ULONG,
5157
5158 // Fields appended in 5.0 (Windows 2000):
5159 PostProcessInitRoutine: PVOID,
5160 TlsExpansionBitmap: *RTL_BITMAP,
5161 TlsExpansionBitmapBits: [32]ULONG,
5162 SessionId: ULONG,
5163 // note: there is padding here on 64 bit
5164 // Versions: 5.1+
5165 AppCompatFlags: ULARGE_INTEGER,
5166 AppCompatFlagsUser: ULARGE_INTEGER,
5167 ShimData: PVOID,
5168 // Versions: 5.0+
5169 AppCompatInfo: PVOID,
5170 CSDVersion: UNICODE_STRING,
5171
5172 // Fields appended in 5.1 (Windows XP):
5173 ActivationContextData: *const ACTIVATION_CONTEXT_DATA,
5174 ProcessAssemblyStorageMap: *ASSEMBLY_STORAGE_MAP,
5175 SystemDefaultActivationData: *const ACTIVATION_CONTEXT_DATA,
5176 SystemAssemblyStorageMap: *ASSEMBLY_STORAGE_MAP,
5177 MinimumStackCommit: ULONG_PTR,
5178
5179 // Fields appended in 5.2 (Windows Server 2003):
5180 FlsCallback: *FLS_CALLBACK_INFO,
5181 FlsListHead: LIST_ENTRY,
5182 FlsBitmap: *RTL_BITMAP,
5183 FlsBitmapBits: [4]ULONG,
5184 FlsHighIndex: ULONG,
5185
5186 // Fields appended in 6.0 (Windows Vista):
5187 WerRegistrationData: PVOID,
5188 WerShipAssertPtr: PVOID,
5189
5190 // Fields appended in 6.1 (Windows 7):
5191 pUnused: PVOID, // previously pContextData
5192 pImageHeaderHash: PVOID,
5193
5194 /// TODO: https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/tracingflags.htm
5195 TracingFlags: ULONG,
5196
5197 // Fields appended in 6.2 (Windows 8):
5198 /// Base address in the CSRSS address space of the memory region shared with the CSR server.
5199 CsrServerReadOnlySharedMemoryBase: ULONGLONG,
5200
5201 // Fields appended in 1511:
5202 TppWorkerpListLock: ULONG,
5203 TppWorkerpList: LIST_ENTRY,
5204 WaitOnAddressHashTable: [0x80]PVOID,
5205
5206 // Fields appended in 1709:
5207 TelemetryCoverageHeader: PVOID,
5208 CloudFileFlags: ULONG,
5209
5210 /// Details of this structure are unknown, but the existence of the field at offset 8 is known
5211 /// from experimentation and from reverse-engineering kernelbase.dll.
5212 const UnknownStaticServerDataIndirection = extern struct {
5213 unknown: u64,
5214 /// In the CSRSS address space.
5215 base_static_server_data_addr: u64,
5216 };
5217};
5218
5219/// The `PEB_LDR_DATA` structure is the main record of what modules are loaded in a process.
5220/// It is essentially the head of three double-linked lists of `LDR.DATA_TABLE_ENTRY` structures which each represent one loaded module.
5221///
5222/// Microsoft documentation of this is incomplete, the fields here are taken from various resources including:
5223/// - https://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb_ldr_data.htm
5224pub const PEB_LDR_DATA = extern struct {
5225 // Versions: 3.51 and higher
5226 /// The size in bytes of the structure
5227 Length: ULONG,
5228
5229 /// TRUE if the structure is prepared.
5230 Initialized: BOOLEAN,
5231
5232 SsHandle: PVOID,
5233 InLoadOrderModuleList: LIST_ENTRY,
5234 InMemoryOrderModuleList: LIST_ENTRY,
5235 InInitializationOrderModuleList: LIST_ENTRY,
5236
5237 // Versions: 5.1 and higher
5238
5239 /// No known use of this field is known in Windows 8 and higher.
5240 EntryInProgress: PVOID,
5241
5242 // Versions: 6.0 from Windows Vista SP1, and higher
5243 ShutdownInProgress: BOOLEAN,
5244
5245 /// Though ShutdownThreadId is declared as a HANDLE,
5246 /// it is indeed the thread ID as suggested by its name.
5247 /// It is picked up from the UniqueThread member of the CLIENT_ID in the
5248 /// TEB of the thread that asks to terminate the process.
5249 ShutdownThreadId: HANDLE,
5250};
5251
5252pub const LDR = struct {
5253 /// Microsoft documentation of this is incomplete, the fields here are taken from various resources including:
5254 /// - https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb_ldr_data
5255 /// - https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntldr/ldr_data_table_entry.htm
5256 pub const DATA_TABLE_ENTRY = extern struct {
5257 InLoadOrderLinks: LIST_ENTRY,
5258 InMemoryOrderLinks: LIST_ENTRY,
5259 InInitializationOrderLinks: LIST_ENTRY,
5260 DllBase: PVOID,
5261 EntryPoint: PVOID,
5262 SizeOfImage: ULONG,
5263 FullDllName: UNICODE_STRING,
5264 BaseDllName: UNICODE_STRING,
5265 Reserved5: [3]PVOID,
5266 DUMMYUNIONNAME: extern union {
5267 CheckSum: ULONG,
5268 Reserved6: PVOID,
5269 },
5270 TimeDateStamp: ULONG,
5271 };
5272
5273 pub const DLL_NOTIFICATION = struct {
5274 pub const REASON = enum(ULONG) { LOADED = 1, UNLOADED = 2 };
5275
5276 pub const DATA = extern union {
5277 Loaded: LOADED,
5278 Unloaded: UNLOADED,
5279
5280 pub const LOADED = extern struct {
5281 Flags: REGISTER,
5282 FullDllName: *const UNICODE_STRING,
5283 BaseDllName: *const UNICODE_STRING,
5284 DllBase: PVOID,
5285 SizeOfImage: ULONG,
5286 };
5287
5288 pub const UNLOADED = extern struct {
5289 Flags: REGISTER,
5290 FullDllName: *const UNICODE_STRING,
5291 BaseDllName: *const UNICODE_STRING,
5292 DllBase: PVOID,
5293 SizeOfImage: ULONG,
5294 };
5295 };
5296
5297 pub const COOKIE = *opaque {};
5298
5299 pub const FUNCTION = fn (
5300 NotificationReason: REASON,
5301 NotificationData: *const DATA,
5302 Context: ?PVOID,
5303 ) callconv(.winapi) void;
5304
5305 pub const REGISTER = packed struct(ULONG) {
5306 Reserved0: u32 = 0,
5307 };
5308 };
5309
5310 pub const GET_DLL_HANDLE_EX = packed struct(ULONG) {
5311 UNCHANGED_REFCOUNT: bool = false,
5312 PIN: bool = false,
5313 Reserved2: u30 = 0,
5314 };
5315
5316 pub const GET_PROCEDURE_ADDRESS = packed struct(ULONG) {
5317 DONT_RECORD_FORWARDER: bool = false,
5318 Reserved1: u31 = 0,
5319 };
5320
5321 pub const LOAD = packed struct(ULONG) {
5322 DONT_RESOLVE_DLL_REFERENCES: bool = false,
5323 LIBRARY_AS_DATAFILE: bool = false,
5324 PACKAGED_LIBRARY: bool = false,
5325 WITH_ALTERED_SEARCH_PATH: bool = false,
5326 IGNORE_CODE_AUTHZ_LEVEL: bool = false,
5327 LIBRARY_AS_IMAGE_RESOURCE: bool = false,
5328 LIBRARY_AS_DATAFILE_EXCLUSIVE: bool = false,
5329 LIBRARY_REQUERE_SIGNED_TARGET: bool = false,
5330 LIBRARY_SEARCH_DLL_LOAD_DIR: bool = false,
5331 LIBRARY_SEARCH_USER_DIRS: bool = false,
5332 LIBRARY_SEARCH_SYSTEM32: bool = false,
5333 LIBRARY_SEARCH_DEFAULT_DIRS: bool = false,
5334 };
5335};
5336
5337pub const RTL_USER_PROCESS_PARAMETERS = extern struct {
5338 AllocationSize: ULONG,
5339 Size: ULONG,
5340 Flags: ULONG,
5341 DebugFlags: ULONG,
5342 ConsoleHandle: HANDLE,
5343 ConsoleFlags: ULONG,
5344 hStdInput: HANDLE,
5345 hStdOutput: HANDLE,
5346 hStdError: HANDLE,
5347 CurrentDirectory: CURDIR,
5348 DllPath: UNICODE_STRING,
5349 ImagePathName: UNICODE_STRING,
5350 CommandLine: UNICODE_STRING,
5351 /// Points to a NUL-terminated sequence of NUL-terminated
5352 /// WTF-16 LE encoded `name=value` sequences.
5353 /// Example using string literal syntax:
5354 /// `"NAME=value\x00foo=bar\x00\x00"`
5355 Environment: [*:0]WCHAR,
5356 dwX: ULONG,
5357 dwY: ULONG,
5358 dwXSize: ULONG,
5359 dwYSize: ULONG,
5360 dwXCountChars: ULONG,
5361 dwYCountChars: ULONG,
5362 dwFillAttribute: ULONG,
5363 dwFlags: ULONG,
5364 dwShowWindow: ULONG,
5365 WindowTitle: UNICODE_STRING,
5366 Desktop: UNICODE_STRING,
5367 ShellInfo: UNICODE_STRING,
5368 RuntimeInfo: UNICODE_STRING,
5369 DLCurrentDirectory: [0x20]RTL_DRIVE_LETTER_CURDIR,
5370};
5371
5372pub const RTL_DRIVE_LETTER_CURDIR = extern struct {
5373 Flags: c_ushort,
5374 Length: c_ushort,
5375 TimeStamp: ULONG,
5376 DosPath: UNICODE_STRING,
5377};
5378
5379pub const PPS_POST_PROCESS_INIT_ROUTINE = ?*const fn () callconv(.winapi) void;
5380
5381pub const FILE_DIRECTORY_INFORMATION = extern struct {
5382 NextEntryOffset: ULONG,
5383 FileIndex: ULONG,
5384 CreationTime: LARGE_INTEGER,
5385 LastAccessTime: LARGE_INTEGER,
5386 LastWriteTime: LARGE_INTEGER,
5387 ChangeTime: LARGE_INTEGER,
5388 EndOfFile: LARGE_INTEGER,
5389 AllocationSize: LARGE_INTEGER,
5390 FileAttributes: FILE.ATTRIBUTE,
5391 FileNameLength: ULONG,
5392 FileName: [1]WCHAR,
5393};
5394
5395pub const FILE_BOTH_DIR_INFORMATION = extern struct {
5396 NextEntryOffset: ULONG,
5397 FileIndex: ULONG,
5398 CreationTime: LARGE_INTEGER,
5399 LastAccessTime: LARGE_INTEGER,
5400 LastWriteTime: LARGE_INTEGER,
5401 ChangeTime: LARGE_INTEGER,
5402 EndOfFile: LARGE_INTEGER,
5403 AllocationSize: LARGE_INTEGER,
5404 FileAttributes: FILE.ATTRIBUTE,
5405 FileNameLength: ULONG,
5406 EaSize: ULONG,
5407 ShortNameLength: CHAR,
5408 ShortName: [12]WCHAR,
5409 FileName: [1]WCHAR,
5410};
5411pub const FILE_BOTH_DIRECTORY_INFORMATION = FILE_BOTH_DIR_INFORMATION;
5412
5413/// Helper for iterating a byte buffer of FILE_*_INFORMATION structures (from
5414/// things like NtQueryDirectoryFile calls).
5415pub fn FileInformationIterator(comptime FileInformationType: type) type {
5416 return struct {
5417 byte_offset: usize = 0,
5418 buf: []u8 align(@alignOf(FileInformationType)),
5419
5420 pub fn next(self: *@This()) ?*FileInformationType {
5421 if (self.byte_offset >= self.buf.len) return null;
5422 const cur: *FileInformationType = @ptrCast(@alignCast(&self.buf[self.byte_offset]));
5423 if (cur.NextEntryOffset == 0) {
5424 self.byte_offset = self.buf.len;
5425 } else {
5426 self.byte_offset += cur.NextEntryOffset;
5427 }
5428 return cur;
5429 }
5430 };
5431}
5432
5433pub const IO_APC_ROUTINE = fn (?*anyopaque, *IO_STATUS_BLOCK, ULONG) callconv(.winapi) void;
5434
5435pub const CURDIR = extern struct {
5436 DosPath: UNICODE_STRING,
5437 Handle: HANDLE,
5438};
5439
5440pub const DUPLICATE_SAME_ACCESS = 2;
5441
5442pub const MODULEINFO = extern struct {
5443 lpBaseOfDll: LPVOID,
5444 SizeOfImage: DWORD,
5445 EntryPoint: LPVOID,
5446};
5447
5448pub const OSVERSIONINFOW = extern struct {
5449 dwOSVersionInfoSize: ULONG,
5450 dwMajorVersion: ULONG,
5451 dwMinorVersion: ULONG,
5452 dwBuildNumber: ULONG,
5453 dwPlatformId: ULONG,
5454 szCSDVersion: [128]WCHAR,
5455};
5456pub const RTL_OSVERSIONINFOW = OSVERSIONINFOW;
5457
5458pub const REPARSE_DATA_BUFFER = extern struct {
5459 ReparseTag: IO_REPARSE_TAG,
5460 ReparseDataLength: USHORT,
5461 Reserved: USHORT,
5462 DataBuffer: [1]UCHAR,
5463};
5464pub const SYMBOLIC_LINK_REPARSE_BUFFER = extern struct {
5465 SubstituteNameOffset: USHORT,
5466 SubstituteNameLength: USHORT,
5467 PrintNameOffset: USHORT,
5468 PrintNameLength: USHORT,
5469 Flags: ULONG,
5470 PathBuffer: [1]WCHAR,
5471};
5472pub const MOUNT_POINT_REPARSE_BUFFER = extern struct {
5473 SubstituteNameOffset: USHORT,
5474 SubstituteNameLength: USHORT,
5475 PrintNameOffset: USHORT,
5476 PrintNameLength: USHORT,
5477 PathBuffer: [1]WCHAR,
5478};
5479pub const SYMLINK_FLAG_RELATIVE: ULONG = 0x1;
5480
5481pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;
5482pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2;
5483
5484pub const MOUNTMGR_MOUNT_POINT = extern struct {
5485 SymbolicLinkNameOffset: ULONG,
5486 SymbolicLinkNameLength: USHORT,
5487 Reserved1: USHORT,
5488 UniqueIdOffset: ULONG,
5489 UniqueIdLength: USHORT,
5490 Reserved2: USHORT,
5491 DeviceNameOffset: ULONG,
5492 DeviceNameLength: USHORT,
5493 Reserved3: USHORT,
5494};
5495pub const MOUNTMGR_MOUNT_POINTS = extern struct {
5496 Size: ULONG,
5497 NumberOfMountPoints: ULONG,
5498 MountPoints: [1]MOUNTMGR_MOUNT_POINT,
5499};
5500
5501pub const MOUNTMGR_TARGET_NAME = extern struct {
5502 DeviceNameLength: USHORT,
5503 DeviceName: [1]WCHAR,
5504};
5505pub const MOUNTMGR_VOLUME_PATHS = extern struct {
5506 MultiSzLength: ULONG,
5507 MultiSz: [1]WCHAR,
5508};
5509
5510pub const SRWLOCK_INIT = SRWLOCK{};
5511pub const SRWLOCK = extern struct {
5512 Ptr: ?PVOID = null,
5513};
5514
5515pub const CONDITION_VARIABLE_INIT = CONDITION_VARIABLE{};
5516pub const CONDITION_VARIABLE = extern struct {
5517 Ptr: ?PVOID = null,
5518};
5519
5520/// Processor feature enumeration.
5521pub const PF = enum(DWORD) {
5522 /// On a Pentium, a floating-point precision error can occur in rare circumstances.
5523 FLOATING_POINT_PRECISION_ERRATA = 0,
5524
5525 /// Floating-point operations are emulated using software emulator.
5526 /// This function returns a nonzero value if floating-point operations are emulated; otherwise, it returns zero.
5527 FLOATING_POINT_EMULATED = 1,
5528
5529 /// The atomic compare and exchange operation (cmpxchg) is available.
5530 COMPARE_EXCHANGE_DOUBLE = 2,
5531
5532 /// The MMX instruction set is available.
5533 MMX_INSTRUCTIONS_AVAILABLE = 3,
5534
5535 PPC_MOVEMEM_64BIT_OK = 4,
5536 ALPHA_BYTE_INSTRUCTIONS = 5,
5537
5538 /// The SSE instruction set is available.
5539 XMMI_INSTRUCTIONS_AVAILABLE = 6,
5540
5541 /// The 3D-Now instruction is available.
5542 @"3DNOW_INSTRUCTIONS_AVAILABLE" = 7,
5543
5544 /// The RDTSC instruction is available.
5545 RDTSC_INSTRUCTION_AVAILABLE = 8,
5546
5547 /// The processor is PAE-enabled.
5548 PAE_ENABLED = 9,
5549
5550 /// The SSE2 instruction set is available.
5551 XMMI64_INSTRUCTIONS_AVAILABLE = 10,
5552
5553 SSE_DAZ_MODE_AVAILABLE = 11,
5554
5555 /// Data execution prevention is enabled.
5556 NX_ENABLED = 12,
5557
5558 /// The SSE3 instruction set is available.
5559 SSE3_INSTRUCTIONS_AVAILABLE = 13,
5560
5561 /// The atomic compare and exchange 128-bit operation (cmpxchg16b) is available.
5562 COMPARE_EXCHANGE128 = 14,
5563
5564 /// The atomic compare 64 and exchange 128-bit operation (cmp8xchg16) is available.
5565 COMPARE64_EXCHANGE128 = 15,
5566
5567 /// The processor channels are enabled.
5568 CHANNELS_ENABLED = 16,
5569
5570 /// The processor implements the XSAVI and XRSTOR instructions.
5571 XSAVE_ENABLED = 17,
5572
5573 /// The VFP/Neon: 32 x 64bit register bank is present.
5574 /// This flag has the same meaning as PF_ARM_VFP_EXTENDED_REGISTERS.
5575 ARM_VFP_32_REGISTERS_AVAILABLE = 18,
5576
5577 /// This ARM processor implements the ARM v8 NEON instruction set.
5578 ARM_NEON_INSTRUCTIONS_AVAILABLE = 19,
5579
5580 /// Second Level Address Translation is supported by the hardware.
5581 SECOND_LEVEL_ADDRESS_TRANSLATION = 20,
5582
5583 /// Virtualization is enabled in the firmware and made available by the operating system.
5584 VIRT_FIRMWARE_ENABLED = 21,
5585
5586 /// RDFSBASE, RDGSBASE, WRFSBASE, and WRGSBASE instructions are available.
5587 RDWRFSGBASE_AVAILABLE = 22,
5588
5589 /// _fastfail() is available.
5590 FASTFAIL_AVAILABLE = 23,
5591
5592 /// The divide instruction_available.
5593 ARM_DIVIDE_INSTRUCTION_AVAILABLE = 24,
5594
5595 /// The 64-bit load/store atomic instructions are available.
5596 ARM_64BIT_LOADSTORE_ATOMIC = 25,
5597
5598 /// The external cache is available.
5599 ARM_EXTERNAL_CACHE_AVAILABLE = 26,
5600
5601 /// The floating-point multiply-accumulate instruction is available.
5602 ARM_FMAC_INSTRUCTIONS_AVAILABLE = 27,
5603
5604 RDRAND_INSTRUCTION_AVAILABLE = 28,
5605
5606 /// This ARM processor implements the ARM v8 instructions set.
5607 ARM_V8_INSTRUCTIONS_AVAILABLE = 29,
5608
5609 /// This ARM processor implements the ARM v8 extra cryptographic instructions (i.e., AES, SHA1 and SHA2).
5610 ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE = 30,
5611
5612 /// This ARM processor implements the ARM v8 extra CRC32 instructions.
5613 ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE = 31,
5614
5615 RDTSCP_INSTRUCTION_AVAILABLE = 32,
5616 RDPID_INSTRUCTION_AVAILABLE = 33,
5617
5618 /// This ARM processor implements the ARM v8.1 atomic instructions (e.g., CAS, SWP).
5619 ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE = 34,
5620
5621 MONITORX_INSTRUCTION_AVAILABLE = 35,
5622
5623 /// The SSSE3 instruction set is available.
5624 SSSE3_INSTRUCTIONS_AVAILABLE = 36,
5625
5626 /// The SSE4_1 instruction set is available.
5627 SSE4_1_INSTRUCTIONS_AVAILABLE = 37,
5628
5629 /// The SSE4_2 instruction set is available.
5630 SSE4_2_INSTRUCTIONS_AVAILABLE = 38,
5631
5632 /// The AVX instruction set is available.
5633 AVX_INSTRUCTIONS_AVAILABLE = 39,
5634
5635 /// The AVX2 instruction set is available.
5636 AVX2_INSTRUCTIONS_AVAILABLE = 40,
5637
5638 /// The AVX512F instruction set is available.
5639 AVX512F_INSTRUCTIONS_AVAILABLE = 41,
5640
5641 ERMS_AVAILABLE = 42,
5642
5643 /// This ARM processor implements the ARM v8.2 Dot Product (DP) instructions.
5644 ARM_V82_DP_INSTRUCTIONS_AVAILABLE = 43,
5645
5646 /// This ARM processor implements the ARM v8.3 JavaScript conversion (JSCVT) instructions.
5647 ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE = 44,
5648
5649 /// 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.
5650 ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE = 45,
5651
5652 /// This Arm processor implements the SVE (Scalable Vector Extension) instructions (FEAT_SVE).
5653 ARM_SVE_INSTRUCTIONS_AVAILABLE = 46,
5654
5655 /// This Arm processor implements the SVE2 instructions (FEAT_SVE2).
5656 ARM_SVE2_INSTRUCTIONS_AVAILABLE = 47,
5657
5658 /// This Arm processor implements the SVE2.1 instructions (FEAT_SVE2p1).
5659 ARM_SVE2_1_INSTRUCTIONS_AVAILABLE = 48,
5660
5661 /// This Arm processor implements the SVE AES instructions (FEAT_SVE_AES).
5662 ARM_SVE_AES_INSTRUCTIONS_AVAILABLE = 49,
5663
5664 /// This Arm processor implements the SVE 128-bit polynomial multiply long instructions (FEAT_SVE_PMULL128).
5665 ARM_SVE_PMULL128_INSTRUCTIONS_AVAILABLE = 50,
5666
5667 /// This Arm processor implements the SVE bit permute instructions (FEAT_SVE_BitPerm).
5668 ARM_SVE_BITPERM_INSTRUCTIONS_AVAILABLE = 51,
5669
5670 /// This Arm processor implements the SVE BF16 (BFloat16) instructions (FEAT_BF16).
5671 ARM_SVE_BF16_INSTRUCTIONS_AVAILABLE = 52,
5672
5673 /// This Arm processor implements the SVE EBF16 (Extended BFloat16) instructions (FEAT_EBF16).
5674 ARM_SVE_EBF16_INSTRUCTIONS_AVAILABLE = 53,
5675
5676 /// This Arm processor implements the SVE B16B16 instructions (FEAT_SVE_B16B16).
5677 ARM_SVE_B16B16_INSTRUCTIONS_AVAILABLE = 54,
5678
5679 /// This Arm processor implements the SVE SHA-3 cryptographic instructions (FEAT_SVE_SHA3).
5680 ARM_SVE_SHA3_INSTRUCTIONS_AVAILABLE = 55,
5681
5682 /// This Arm processor implements the SVE SM4 cryptographic instructions (FEAT_SVE_SM4).
5683 ARM_SVE_SM4_INSTRUCTIONS_AVAILABLE = 56,
5684
5685 /// This Arm processor implements the SVE I8MM (Int8 matrix multiply) instructions (FEAT_I8MM).
5686 ARM_SVE_I8MM_INSTRUCTIONS_AVAILABLE = 57,
5687
5688 /// This Arm processor implements the SVE F32MM (FP32 matrix multiply) instructions (FEAT_F32MM).
5689 ARM_SVE_F32MM_INSTRUCTIONS_AVAILABLE = 58,
5690
5691 /// This Arm processor implements the SVE F64MM (FP64 matrix multiply) instructions (FEAT_F64MM).
5692 ARM_SVE_F64MM_INSTRUCTIONS_AVAILABLE = 59,
5693
5694 /// This x64 processor implements the BMI2 instruction set.
5695 BMI2_INSTRUCTIONS_AVAILABLE = 60,
5696
5697 /// This x64 processor implements the MOVDIR64B instruction.
5698 MOVDIR64B_INSTRUCTION_AVAILABLE = 61,
5699
5700 /// This Arm processor implements the LSE2 atomic instructions (FEAT_LSE2).
5701 ARM_LSE2_AVAILABLE = 62,
5702
5703 /// This Arm processor implements the SHA-3 cryptographic instructions (FEAT_SHA3).
5704 ARM_SHA3_INSTRUCTIONS_AVAILABLE = 64,
5705
5706 /// This Arm processor implements the SHA-512 cryptographic instructions (FEAT_SHA512).
5707 ARM_SHA512_INSTRUCTIONS_AVAILABLE = 65,
5708
5709 /// This Arm processor implements the I8MM (Int8 matrix multiply) NEON instructions (FEAT_I8MM).
5710 ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE = 66,
5711
5712 /// This Arm processor implements the FP16 (half-precision floating point) NEON instructions (FEAT_FP16).
5713 ARM_V82_FP16_INSTRUCTIONS_AVAILABLE = 67,
5714
5715 /// This Arm processor implements the BF16 (BFloat16) NEON instructions (FEAT_BF16).
5716 ARM_V86_BF16_INSTRUCTIONS_AVAILABLE = 68,
5717
5718 /// This Arm processor implements the EBF16 (Extended BFloat16) NEON instructions (FEAT_EBF16).
5719 ARM_V86_EBF16_INSTRUCTIONS_AVAILABLE = 69,
5720
5721 /// This Arm processor implements the SME (Scalable Matrix Extension) instructions (FEAT_SME).
5722 ARM_SME_INSTRUCTIONS_AVAILABLE = 70,
5723
5724 /// This Arm processor implements the SME2 instructions (FEAT_SME2).
5725 ARM_SME2_INSTRUCTIONS_AVAILABLE = 71,
5726
5727 /// This Arm processor implements the SME2.1 instructions (FEAT_SME2p1).
5728 ARM_SME2_1_INSTRUCTIONS_AVAILABLE = 72,
5729
5730 /// This Arm processor implements the SME2.2 instructions (FEAT_SME2p2).
5731 ARM_SME2_2_INSTRUCTIONS_AVAILABLE = 73,
5732
5733 /// This Arm processor implements the SVE AES instructions when in Streaming SVE mode (FEAT_SSVE_AES).
5734 ARM_SME_AES_INSTRUCTIONS_AVAILABLE = 74,
5735
5736 /// This Arm processor implements the SVE bit permute instructions when in Streaming SVE mode (FEAT_SSVE_BitPerm).
5737 ARM_SME_SBITPERM_INSTRUCTIONS_AVAILABLE = 75,
5738
5739 /// This Arm processor implements the SVE FMMLA (widening, 4-way, FP8 to FP16) instruction when in Streaming SVE mode (FEAT_SSVE_F8F16MM).
5740 ARM_SME_SF8MM4_INSTRUCTIONS_AVAILABLE = 76,
5741
5742 /// This Arm processor implements the SVE FMMLA (widening, 8-way, FP8 to FP32) instruction when in Streaming SVE mode (FEAT_SSVE_F8F32MM).
5743 ARM_SME_SF8MM8_INSTRUCTIONS_AVAILABLE = 77,
5744
5745 /// This Arm processor implements the SVE2 FP8DOT2 instructions when in Streaming SVE mode (FEAT_SSVE_FP8DOT2).
5746 ARM_SME_SF8DP2_INSTRUCTIONS_AVAILABLE = 78,
5747
5748 /// This Arm processor implements the SVE2 FP8DOT4 instructions when in Streaming SVE mode (FEAT_SSVE_FP8DOT4).
5749 ARM_SME_SF8DP4_INSTRUCTIONS_AVAILABLE = 79,
5750
5751 /// This Arm processor implements the SVE2 FP8FMA instructions when in Streaming SVE mode (FEAT_SSVE_FP8FMA).
5752 ARM_SME_SF8FMA_INSTRUCTIONS_AVAILABLE = 80,
5753
5754 /// This Arm processor implements the SME F8F32 instructions (FEAT_SME_F8F32).
5755 ARM_SME_F8F32_INSTRUCTIONS_AVAILABLE = 81,
5756
5757 /// This Arm processor implements the SME F8F16 instructions (FEAT_SME_F8F16).
5758 ARM_SME_F8F16_INSTRUCTIONS_AVAILABLE = 82,
5759
5760 /// This Arm processor implements the SME F16F16 instructions (FEAT_SME_F16F16).
5761 ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE = 83,
5762
5763 /// This Arm processor implements the SME B16B16 instructions (FEAT_SME_B16B16).
5764 ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE = 84,
5765
5766 /// This Arm processor implements the SME F64F64 instructions (FEAT_SME_F64F64).
5767 ARM_SME_F64F64_INSTRUCTIONS_AVAILABLE = 85,
5768
5769 /// This Arm processor implements the SME I16I64 instructions (FEAT_SME_I16I64).
5770 ARM_SME_I16I64_INSTRUCTIONS_AVAILABLE = 86,
5771
5772 /// This Arm processor implements the SME LUTv2 instructions (FEAT_SME_LUTv2).
5773 ARM_SME_LUTv2_INSTRUCTIONS_AVAILABLE = 87,
5774
5775 /// This Arm processor implements SME FA64 (Full AArch64 instruction set when in Streaming SVE mode) (FEAT_SME_FA64).
5776 ARM_SME_FA64_INSTRUCTIONS_AVAILABLE = 88,
5777
5778 /// This x64 processor implements the UMONITOR instruction.
5779 UMONITOR_INSTRUCTION_AVAILABLE = 89,
5780};
5781
5782pub const MAX_WOW64_SHARED_ENTRIES = 16;
5783pub const PROCESSOR_FEATURE_MAX = 64;
5784pub const MAXIMUM_XSTATE_FEATURES = 64;
5785
5786pub const KSYSTEM_TIME = extern struct {
5787 LowPart: ULONG,
5788 High1Time: LONG,
5789 High2Time: LONG,
5790};
5791
5792pub const NT_PRODUCT_TYPE = enum(INT) {
5793 NtProductWinNt = 1,
5794 NtProductLanManNt,
5795 NtProductServer,
5796};
5797
5798pub const ALTERNATIVE_ARCHITECTURE_TYPE = enum(INT) {
5799 StandardDesign,
5800 NEC98x86,
5801 EndAlternatives,
5802};
5803
5804pub const XSTATE_FEATURE = extern struct {
5805 Offset: ULONG,
5806 Size: ULONG,
5807};
5808
5809pub const XSTATE_CONFIGURATION = extern struct {
5810 EnabledFeatures: ULONG64,
5811 Size: ULONG,
5812 OptimizedSave: ULONG,
5813 Features: [MAXIMUM_XSTATE_FEATURES]XSTATE_FEATURE,
5814};
5815
5816/// Shared Kernel User Data
5817pub const KUSER_SHARED_DATA = extern struct {
5818 TickCountLowDeprecated: ULONG,
5819 TickCountMultiplier: ULONG,
5820 InterruptTime: KSYSTEM_TIME,
5821 SystemTime: KSYSTEM_TIME,
5822 TimeZoneBias: KSYSTEM_TIME,
5823 ImageNumberLow: USHORT,
5824 ImageNumberHigh: USHORT,
5825 NtSystemRoot: [260]WCHAR,
5826 MaxStackTraceDepth: ULONG,
5827 CryptoExponent: ULONG,
5828 TimeZoneId: ULONG,
5829 LargePageMinimum: ULONG,
5830 AitSamplingValue: ULONG,
5831 AppCompatFlag: ULONG,
5832 RNGSeedVersion: ULONGLONG,
5833 GlobalValidationRunlevel: ULONG,
5834 TimeZoneBiasStamp: LONG,
5835 NtBuildNumber: ULONG,
5836 NtProductType: NT_PRODUCT_TYPE,
5837 ProductTypeIsValid: BOOLEAN,
5838 Reserved0: [1]BOOLEAN,
5839 NativeProcessorArchitecture: USHORT,
5840 NtMajorVersion: ULONG,
5841 NtMinorVersion: ULONG,
5842 ProcessorFeatures: [PROCESSOR_FEATURE_MAX]BOOLEAN,
5843 Reserved1: ULONG,
5844 Reserved3: ULONG,
5845 TimeSlip: ULONG,
5846 AlternativeArchitecture: ALTERNATIVE_ARCHITECTURE_TYPE,
5847 BootId: ULONG,
5848 SystemExpirationDate: LARGE_INTEGER,
5849 SuiteMaskY: ULONG,
5850 KdDebuggerEnabled: BOOLEAN,
5851 DummyUnion1: extern union {
5852 MitigationPolicies: UCHAR,
5853 Alt: packed struct(u8) {
5854 NXSupportPolicy: u2,
5855 SEHValidationPolicy: u2,
5856 CurDirDevicesSkippedForDlls: u2,
5857 Reserved: u2,
5858 },
5859 },
5860 CyclesPerYield: USHORT,
5861 ActiveConsoleId: ULONG,
5862 DismountCount: ULONG,
5863 ComPlusPackage: ULONG,
5864 LastSystemRITEventTickCount: ULONG,
5865 NumberOfPhysicalPages: ULONG,
5866 SafeBootMode: BOOLEAN,
5867 DummyUnion2: extern union {
5868 VirtualizationFlags: UCHAR,
5869 Alt: packed struct(u8) {
5870 ArchStartedInEl2: u1,
5871 QcSlIsSupported: u1,
5872 SpareBits: u6,
5873 },
5874 },
5875 Reserved12: [2]UCHAR,
5876 DummyUnion3: extern union {
5877 SharedDataFlags: ULONG,
5878 Alt: packed struct(u32) {
5879 DbgErrorPortPresent: u1,
5880 DbgElevationEnabled: u1,
5881 DbgVirtEnabled: u1,
5882 DbgInstallerDetectEnabled: u1,
5883 DbgLkgEnabled: u1,
5884 DbgDynProcessorEnabled: u1,
5885 DbgConsoleBrokerEnabled: u1,
5886 DbgSecureBootEnabled: u1,
5887 DbgMultiSessionSku: u1,
5888 DbgMultiUsersInSessionSku: u1,
5889 DbgStateSeparationEnabled: u1,
5890 SpareBits: u21,
5891 },
5892 },
5893 DataFlagsPad: [1]ULONG,
5894 TestRetInstruction: ULONGLONG,
5895 QpcFrequency: LONGLONG,
5896 SystemCall: ULONG,
5897 Reserved2: ULONG,
5898 SystemCallPad: [2]ULONGLONG,
5899 DummyUnion4: extern union {
5900 TickCount: KSYSTEM_TIME,
5901 TickCountQuad: ULONG64,
5902 Alt: extern struct {
5903 ReservedTickCountOverlay: [3]ULONG,
5904 TickCountPad: [1]ULONG,
5905 },
5906 },
5907 Cookie: ULONG,
5908 CookiePad: [1]ULONG,
5909 ConsoleSessionForegroundProcessId: LONGLONG,
5910 TimeUpdateLock: ULONGLONG,
5911 BaselineSystemTimeQpc: ULONGLONG,
5912 BaselineInterruptTimeQpc: ULONGLONG,
5913 QpcSystemTimeIncrement: ULONGLONG,
5914 QpcInterruptTimeIncrement: ULONGLONG,
5915 QpcSystemTimeIncrementShift: UCHAR,
5916 QpcInterruptTimeIncrementShift: UCHAR,
5917 UnparkedProcessorCount: USHORT,
5918 EnclaveFeatureMask: [4]ULONG,
5919 TelemetryCoverageRound: ULONG,
5920 UserModeGlobalLogger: [16]USHORT,
5921 ImageFileExecutionOptions: ULONG,
5922 LangGenerationCount: ULONG,
5923 Reserved4: ULONGLONG,
5924 InterruptTimeBias: ULONGLONG,
5925 QpcBias: ULONGLONG,
5926 ActiveProcessorCount: ULONG,
5927 ActiveGroupCount: UCHAR,
5928 Reserved9: UCHAR,
5929 DummyUnion5: extern union {
5930 QpcData: USHORT,
5931 Alt: extern struct {
5932 QpcBypassEnabled: UCHAR,
5933 QpcShift: UCHAR,
5934 },
5935 },
5936 TimeZoneBiasEffectiveStart: LARGE_INTEGER,
5937 TimeZoneBiasEffectiveEnd: LARGE_INTEGER,
5938 XState: XSTATE_CONFIGURATION,
5939 FeatureConfigurationChangeStamp: KSYSTEM_TIME,
5940 Spare: ULONG,
5941 UserPointerAuthMask: ULONG64,
5942};
5943
5944/// Read-only user-mode address for the shared data.
5945/// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntexapi_x/kuser_shared_data/index.htm
5946/// https://msrc-blog.microsoft.com/2022/04/05/randomizing-the-kuser_shared_data-structure-on-windows/
5947pub const SharedUserData: *const KUSER_SHARED_DATA = @ptrFromInt(0x7FFE0000);
5948
5949pub fn IsProcessorFeaturePresent(feature: PF) bool {
5950 if (@backingInt(feature) >= PROCESSOR_FEATURE_MAX) return false;
5951 return SharedUserData.ProcessorFeatures[@backingInt(feature)].toBool();
5952}
5953
5954// https://github.com/reactos/reactos/blob/master/sdk/include/ndk/pstypes.h#L977-L983
5955pub const KERNEL_USER_TIMES = extern struct {
5956 CreationTime: LARGE_INTEGER,
5957 ExitTime: LARGE_INTEGER,
5958 KernelTime: LARGE_INTEGER,
5959 UserTime: LARGE_INTEGER,
5960};
5961
5962pub fn wtf8ToWtf16Le(wtf16le: []u16, wtf8: []const u8) error{ BadPathName, NameTooLong }!usize {
5963 // Each u8 in UTF-8/WTF-8 correlates to at most one u16 in UTF-16LE/WTF-16LE.
5964 if (wtf16le.len < wtf8.len) {
5965 const utf16_len = std.unicode.calcUtf16LeLenImpl(wtf8, .can_encode_surrogate_half) catch
5966 return error.BadPathName;
5967 if (utf16_len > wtf16le.len)
5968 return error.NameTooLong;
5969 }
5970 return std.unicode.wtf8ToWtf16Le(wtf16le, wtf8) catch |err| switch (err) {
5971 error.InvalidWtf8 => return error.BadPathName,
5972 };
5973}
5974
5975/// Returns the path to the system directory, typically "C:\\WINDOWS\\System32".
5976///
5977/// Equivalent to `GetSystemDirectoryW` in kernel32.
5978pub fn getSystemDirectoryWtf16Le() [:0]const u16 {
5979 const ssd: *const BASE_STATIC_SERVER_DATA = @ptrCast(@alignCast(relocateCsrssAddress(
5980 peb().ReadOnlyStaticServerData.base_static_server_data_addr,
5981 )));
5982 return ssd.windows_system_directory.relocate().sliceZ();
5983}
5984// https://github.com/reactos/reactos/blob/4b75ec5508d47b726d1210e24f5a849dae4e3bda/sdk/include/reactos/subsys/win/base.h#L119
5985const BASE_STATIC_SERVER_DATA = extern struct {
5986 windows_directory: ForeignString,
5987 windows_system_directory: ForeignString,
5988 named_object_directory: ForeignString,
5989 /// This matches the 64-bit version of `UNICODE_STRING`---even on 32-bit targets, this string is
5990 /// from 64-bit code (since it comes from CSRSS which is running outside of WOW64).
5991 const ForeignString = extern struct {
5992 length: u16,
5993 maximum_length: u16,
5994 /// Address in the CSRSS address space. To convert this to a valid pointer in *our* address
5995 /// space, see `relocateCsrssAddress` (or the `ForeignString.relocate` wrapper function).
5996 buffer_address: u64,
5997 fn relocate(str: ForeignString) UNICODE_STRING {
5998 return .{
5999 .Length = str.length,
6000 .MaximumLength = str.maximum_length,
6001 .Buffer = @ptrCast(@alignCast(@constCast(relocateCsrssAddress(str.buffer_address)))),
6002 };
6003 }
6004 };
6005};
6006/// Takes an address in the CSRSS address space's mapped view of the shared memory region, and
6007/// returns the corresponding address in *our* mapped view of the shared memory region.
6008fn relocateCsrssAddress(addr: u64) *const anyopaque {
6009 const base: [*]const u8 = @ptrCast(peb().ReadOnlySharedMemoryBase);
6010 const offset: usize = @intCast(addr - peb().CsrServerReadOnlySharedMemoryBase);
6011 return base + offset;
6012}