Commit 153afed877
Changed files (3)
lib
std
os
windows
target
lib/std/os/windows/ntdll.zig
@@ -253,3 +253,9 @@ pub extern "ntdll" fn NtUnlockFile(
Length: *const LARGE_INTEGER,
Key: ?*ULONG,
) callconv(WINAPI) NTSTATUS;
+
+pub extern "ntdll" fn NtOpenKey(
+ KeyHandle: *HANDLE,
+ DesiredAccess: ACCESS_MASK,
+ ObjectAttributes: OBJECT_ATTRIBUTES,
+) callconv(WINAPI) NTSTATUS;
lib/std/os/windows.zig
@@ -2504,6 +2504,7 @@ pub const STANDARD_RIGHTS_READ = READ_CONTROL;
pub const STANDARD_RIGHTS_WRITE = READ_CONTROL;
pub const STANDARD_RIGHTS_EXECUTE = READ_CONTROL;
pub const STANDARD_RIGHTS_REQUIRED = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER;
+pub const MAXIMUM_ALLOWED = 0x02000000;
// disposition for NtCreateFile
pub const FILE_SUPERSEDE = 0;
@@ -2872,9 +2873,11 @@ pub const PROV_RSA_FULL = 1;
pub const REGSAM = ACCESS_MASK;
pub const ACCESS_MASK = DWORD;
-pub const HKEY = *opaque {};
pub const LSTATUS = LONG;
+pub const HKEY = HANDLE;
+pub const HKEY_LOCAL_MACHINE: HKEY = @intToPtr(HKEY, 0x80000002);
+
pub const FILE_NOTIFY_INFORMATION = extern struct {
NextEntryOffset: DWORD,
Action: DWORD,
@@ -4017,3 +4020,187 @@ pub fn IsProcessorFeaturePresent(feature: PF) bool {
if (@enumToInt(feature) >= PROCESSOR_FEATURE_MAX) return false;
return SharedUserData.ProcessorFeatures[@enumToInt(feature)] == 1;
}
+
+pub const KEY_QUERY_VALUE = 0x0001;
+
+/// Open symbolic link.
+pub const REG_OPTION_OPEN_LINK: DWORD = 0x8;
+
+inline fn IsPredefKey(hkey: HKEY) bool {
+ return @ptrToInt(hkey) & 0xF0000000 == 0x80000000;
+}
+
+inline fn GetPredefKeyIndex(hkey: HKEY) usize {
+ return @ptrToInt(hkey) & 0x0FFFFFFF;
+}
+
+inline fn ClosePredefKey(hkey: HKEY) void {
+ if (@ptrToInt(hkey) & 0x1 != 0) {
+ assert(ntdll.NtClose(hkey) == .SUCCESS);
+ }
+}
+
+const MAX_DEFAULT_HANDLES = 6;
+pub const REG_MAX_NAME_SIZE = 256;
+
+pub const RegOpenKeyOpts = struct {
+ ulOptions: DWORD = 0,
+ samDesired: ACCESS_MASK = KEY_QUERY_VALUE,
+};
+
+/// Pulls existing key from the registry.
+pub fn RegOpenKey(hkey: HKEY, lpSubKey: []const u16, opts: RegOpenKeyOpts) !HKEY {
+ if (IsPredefKey(hkey) and lpSubKey.len == 0) {
+ return hkey;
+ }
+
+ const key_handle = try MapDefaultKey(hkey);
+ defer ClosePredefKey(key_handle);
+
+ var subkey_string: UNICODE_STRING = undefined;
+ if (lpSubKey.len == 0 or mem.eql(u16, &[_]u16{'\\'}, lpSubKey)) {
+ subkey_string = .{
+ .Length = 0,
+ .MaximumLength = 0,
+ .Buffer = @intToPtr([*]u16, @ptrToInt(&[0]u16{})),
+ };
+ } else {
+ const len_bytes = math.cast(u16, lpSubKey.len * 2) orelse return error.NameTooLong;
+ subkey_string = .{
+ .Length = len_bytes,
+ .MaximumLength = len_bytes,
+ .Buffer = @intToPtr([*]u16, @ptrToInt(lpSubKey.ptr)),
+ };
+ }
+
+ var attributes: ULONG = OBJ_CASE_INSENSITIVE;
+ if (opts.ulOptions & REG_OPTION_OPEN_LINK != 0) {
+ attributes |= OBJ_OPENLINK;
+ }
+
+ var attr = OBJECT_ATTRIBUTES{
+ .Length = @sizeOf(OBJECT_ATTRIBUTES),
+ .RootDirectory = key_handle,
+ .Attributes = attributes,
+ .ObjectName = &subkey_string,
+ .SecurityDescriptor = null,
+ .SecurityQualityOfService = null,
+ };
+
+ var result: HKEY = undefined;
+ const rc = ntdll.NtOpenKey(
+ &result,
+ opts.samDesired,
+ attr,
+ );
+ switch (rc) {
+ .SUCCESS => return result,
+ else => return unexpectedStatus(rc),
+ }
+}
+
+pub fn RegCloseKey(hkey: HKEY) void {
+ if (IsPredefKey(hkey)) return;
+ assert(ntdll.NtClose(hkey) == .SUCCESS);
+}
+
+extern var DefaultHandleHKUDisabled: BOOLEAN;
+extern var DefaultHandlesDisabled: BOOLEAN;
+extern var DefaultHandleTable: [MAX_DEFAULT_HANDLES]?HANDLE;
+
+fn MapDefaultKey(key: HKEY) !HANDLE {
+ if (!IsPredefKey(key)) return @intToPtr(HANDLE, @ptrToInt(key) & ~@as(usize, 0x1));
+
+ const index = GetPredefKeyIndex(key);
+ if (index >= MAX_DEFAULT_HANDLES) {
+ return error.InvalidParameter;
+ }
+
+ const def_disabled = if (key == HKEY_LOCAL_MACHINE) DefaultHandleHKUDisabled else DefaultHandlesDisabled;
+
+ var handle: HANDLE = undefined;
+ var do_open: bool = true;
+
+ if (def_disabled != 0) {
+ const tmp = DefaultHandleTable[index];
+ if (tmp) |h| {
+ do_open = false;
+ handle = h;
+ }
+ }
+
+ if (do_open) {
+ handle = try OpenPredefinedKey(index);
+ }
+
+ if (def_disabled == 0) {
+ handle = @intToPtr(HANDLE, @ptrToInt(handle) | 0x1);
+ }
+
+ return handle;
+}
+
+fn OpenPredefinedKey(index: usize) !HANDLE {
+ switch (index) {
+ 0 => {
+ // HKEY_CLASSES_ROOT
+ return error.Unimplemented;
+ },
+ 1 => {
+ // HKEY_CURRENT_USER
+ return error.Unimplemented;
+ },
+ 2 => {
+ // HKEY_LOCAL_MACHINE
+ return OpenLocalMachineKey();
+ },
+ 3 => {
+ // HKEY_USERS
+ return error.Unimplemented;
+ },
+ 5 => {
+ // HKEY_CURRENT_CONFIG
+ return error.Unimplemented;
+ },
+ 6 => {
+ // HKEY_DYN_DATA
+ return error.Unimplemented;
+ },
+ else => {
+ return error.InvalidParameter;
+ },
+ }
+}
+
+fn OpenLocalMachineKey() !HANDLE {
+ const path = "\\Registry\\Machine";
+ var path_u16: [REG_MAX_NAME_SIZE]u16 = undefined;
+ const path_len_u16 = try std.unicode.utf8ToUtf16Le(&path_u16, path);
+ const path_len_bytes = @intCast(u16, path_len_u16 * 2);
+
+ var key_name = UNICODE_STRING{
+ .Length = path_len_bytes,
+ .MaximumLength = path_len_bytes,
+ .Buffer = @intToPtr([*]u16, @ptrToInt(&path_u16)),
+ };
+
+ var attr = OBJECT_ATTRIBUTES{
+ .Length = @sizeOf(OBJECT_ATTRIBUTES),
+ .RootDirectory = null,
+ .Attributes = OBJ_CASE_INSENSITIVE,
+ .ObjectName = &key_name,
+ .SecurityDescriptor = null,
+ .SecurityQualityOfService = null,
+ };
+
+ var result: HKEY = undefined;
+ const rc = ntdll.NtOpenKey(
+ &result,
+ MAXIMUM_ALLOWED,
+ attr,
+ );
+ switch (rc) {
+ .SUCCESS => return result,
+ else => return unexpectedStatus(rc),
+ }
+}
lib/std/target/aarch64.zig
@@ -2252,4 +2252,19 @@ pub const cpu = struct {
.v8a,
}),
};
+
+ pub const microsoft_sq3 = CpuModel{
+ .name = "microsoft_sq3",
+ .llvm_name = "generic",
+ .features = featureSet(&[_]Feature{
+ .aes,
+ .crc,
+ .crypto,
+ .dotprod,
+ .fp_armv8,
+ .lse,
+ .neon,
+ .sha2,
+ }),
+ };
};