aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-11-27 14:13:28 +0100
committerJakub Konka <kubkon@jakubkonka.com>2022-11-28 17:07:34 +0100
commitd64d7aaac7650d79a6f5a5c5d0db6730b6a11b2c (patch)
treede2a78212571eae6a327b7c7e2d1e6fc669cc9c2 /lib/std
parent57bda6524b2dbe69c20f25e99c9b136dd0859297 (diff)
downloadzig-d64d7aaac7650d79a6f5a5c5d0db6730b6a11b2c.tar.gz
zig-d64d7aaac7650d79a6f5a5c5d0db6730b6a11b2c.zip
windows: drive the registry helper with actual value set for reg entries
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/os/windows.zig56
-rw-r--r--lib/std/zig/system/windows.zig96
2 files changed, 87 insertions, 65 deletions
diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig
index 06b3cd7d77..d4b796ae77 100644
--- a/lib/std/os/windows.zig
+++ b/lib/std/os/windows.zig
@@ -2981,33 +2981,35 @@ pub const RTL_QUERY_REGISTRY_DELETE = 0x00000040;
/// If the types do not match, the call fails.
pub const RTL_QUERY_REGISTRY_TYPECHECK = 0x00000100;
-/// No value type
-pub const REG_NONE = 0;
-/// Unicode nul terminated string
-pub const REG_SZ = 1;
-/// Unicode nul terminated string (with environment variable references)
-pub const REG_EXPAND_SZ = 2;
-/// Free form binary
-pub const REG_BINARY = 3;
-/// 32-bit number
-pub const REG_DWORD = 4;
-/// 32-bit number (same as REG_DWORD)
-pub const REG_DWORD_LITTLE_ENDIAN = 4;
-/// 32-bit number
-pub const REG_DWORD_BIG_ENDIAN = 5;
-/// Symbolic Link (unicode)
-pub const REG_LINK = 6;
-/// Multiple Unicode strings
-pub const REG_MULTI_SZ = 7;
-/// Resource list in the resource map
-pub const REG_RESOURCE_LIST = 8;
-/// Resource list in the hardware description
-pub const REG_FULL_RESOURCE_DESCRIPTOR = 9;
-pub const REG_RESOURCE_REQUIREMENTS_LIST = 10;
-/// 64-bit number
-pub const REG_QWORD = 11;
-/// 64-bit number (same as REG_QWORD)
-pub const REG_QWORD_LITTLE_ENDIAN = 11;
+pub const REG = struct {
+ /// No value type
+ pub const NONE: ULONG = 0;
+ /// Unicode nul terminated string
+ pub const SZ: ULONG = 1;
+ /// Unicode nul terminated string (with environment variable references)
+ pub const EXPAND_SZ: ULONG = 2;
+ /// Free form binary
+ pub const BINARY: ULONG = 3;
+ /// 32-bit number
+ pub const DWORD: ULONG = 4;
+ /// 32-bit number (same as REG_DWORD)
+ pub const DWORD_LITTLE_ENDIAN: ULONG = 4;
+ /// 32-bit number
+ pub const DWORD_BIG_ENDIAN: ULONG = 5;
+ /// Symbolic Link (unicode)
+ pub const LINK: ULONG = 6;
+ /// Multiple Unicode strings
+ pub const MULTI_SZ: ULONG = 7;
+ /// Resource list in the resource map
+ pub const RESOURCE_LIST: ULONG = 8;
+ /// Resource list in the hardware description
+ pub const FULL_RESOURCE_DESCRIPTOR: ULONG = 9;
+ pub const RESOURCE_REQUIREMENTS_LIST: ULONG = 10;
+ /// 64-bit number
+ pub const QWORD: ULONG = 11;
+ /// 64-bit number (same as REG_QWORD)
+ pub const QWORD_LITTLE_ENDIAN: ULONG = 11;
+};
pub const FILE_NOTIFY_INFORMATION = extern struct {
NextEntryOffset: DWORD,
diff --git a/lib/std/zig/system/windows.zig b/lib/std/zig/system/windows.zig
index 8294fd5b95..e1ab002834 100644
--- a/lib/std/zig/system/windows.zig
+++ b/lib/std/zig/system/windows.zig
@@ -5,6 +5,7 @@ const Target = std.Target;
pub const WindowsVersion = std.Target.Os.WindowsVersion;
pub const PF = std.os.windows.PF;
+pub const REG = std.os.windows.REG;
pub const IsProcessorFeaturePresent = std.os.windows.IsProcessorFeaturePresent;
/// Returns the highest known WindowsVersion deduced from reported runtime information.
@@ -92,7 +93,7 @@ const Armv8CpuInfoImpl = struct {
}
};
-fn getCpuInfoFromRegistry(comptime T: type, core: usize, comptime key: []const u8) !T {
+fn getCpuInfoFromRegistry(core: usize, comptime key: []const u8, value_type: std.os.windows.ULONG) ![]const u8 {
const key_name = std.unicode.utf8ToUtf16LeStringLiteral(key);
// Originally, I wanted to issue a single call with a more complex table structure such that we
@@ -105,37 +106,42 @@ fn getCpuInfoFromRegistry(comptime T: type, core: usize, comptime key: []const u
const topkey = std.unicode.utf8ToUtf16LeStringLiteral("\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor");
- // Technically, a registry value can be as long as 16k u16s. However, MS recommends storing
- // values larger than 2048 in a file rather than directly in the registry, and since we
+ // Technically, a registry value can be as long as 1MB. However, MS recommends storing
+ // values larger than 2048 bytes in a file rather than directly in the registry, and since we
// are only accessing a system hive \Registry\Machine, we stick to MS guidelines.
// https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-element-size-limits
- const max_sz_value = 2048;
+ const max_value_len = 2048;
const ctx: *anyopaque = blk: {
- switch (@typeInfo(T)) {
- .Int => |int| {
- const bits = int.bits;
- var buf: [bits * 8]u8 = undefined;
+ switch (value_type) {
+ REG.NONE => unreachable,
+
+ REG.SZ,
+ REG.EXPAND_SZ,
+ REG.MULTI_SZ,
+ => {
+ var buf: [max_value_len / 2]u16 = undefined;
+ var unicode = std.os.windows.UNICODE_STRING{
+ .Length = max_value_len,
+ .MaximumLength = max_value_len,
+ .Buffer = &buf,
+ };
+ break :blk &unicode;
+ },
+
+ REG.DWORD,
+ REG.DWORD_BIG_ENDIAN,
+ => {
+ var buf: [4]u8 = undefined;
break :blk &buf;
},
- .Pointer => |ptr| switch (ptr.size) {
- .Slice => {
- const child = @typeInfo(ptr.child);
- if (child != .Int and child.Int.bits != 8) {
- @compileError("Unsupported type " ++ @typeName(T) ++ " as registry value");
- }
-
- var buf: [max_sz_value]u16 = undefined;
- var unicode = std.os.windows.UNICODE_STRING{
- .Length = buf.len * 2,
- .MaximumLength = buf.len * 2,
- .Buffer = &buf,
- };
- break :blk &unicode;
- },
- else => @compileError("Unsupported type " ++ @typeName(T) ++ " as registry value"),
+
+ REG.QWORD => {
+ var buf: [8]u8 = undefined;
+ break :blk &buf;
},
- else => @compileError("Unsupported type " ++ @typeName(T) ++ " as registry value"),
+
+ else => unreachable,
}
};
@@ -152,7 +158,7 @@ fn getCpuInfoFromRegistry(comptime T: type, core: usize, comptime key: []const u
.Flags = std.os.windows.RTL_QUERY_REGISTRY_SUBKEY | std.os.windows.RTL_QUERY_REGISTRY_REQUIRED,
.Name = subkey[0..subkey_len :0],
.EntryContext = null,
- .DefaultType = std.os.windows.REG_NONE,
+ .DefaultType = REG.NONE,
.DefaultData = null,
.DefaultLength = 0,
};
@@ -162,7 +168,7 @@ fn getCpuInfoFromRegistry(comptime T: type, core: usize, comptime key: []const u
.Flags = std.os.windows.RTL_QUERY_REGISTRY_DIRECT | std.os.windows.RTL_QUERY_REGISTRY_REQUIRED,
.Name = @intToPtr([*:0]u16, @ptrToInt(key_name)),
.EntryContext = ctx,
- .DefaultType = std.os.windows.REG_NONE,
+ .DefaultType = REG.NONE,
.DefaultData = null,
.DefaultLength = 0,
};
@@ -186,17 +192,31 @@ fn getCpuInfoFromRegistry(comptime T: type, core: usize, comptime key: []const u
null,
);
switch (res) {
- .SUCCESS => switch (@typeInfo(T)) {
- .Int => {
- const entry = @ptrCast(*align(1) const T, table[1].EntryContext);
- return entry.*;
- },
- .Pointer => {
+ .SUCCESS => switch (value_type) {
+ REG.NONE => unreachable,
+
+ REG.SZ,
+ REG.EXPAND_SZ,
+ REG.MULTI_SZ,
+ => {
const entry = @ptrCast(*align(1) const std.os.windows.UNICODE_STRING, table[1].EntryContext);
- var identifier_buf: [max_sz_value * 2]u8 = undefined;
+ var identifier_buf: [max_value_len]u8 = undefined;
const len = try std.unicode.utf16leToUtf8(&identifier_buf, entry.Buffer[0 .. entry.Length / 2]);
- return @as(T, identifier_buf[0..len]);
+ return identifier_buf[0..len];
},
+
+ REG.DWORD,
+ REG.DWORD_BIG_ENDIAN,
+ REG.QWORD,
+ => {
+ const entry = @ptrCast([*]align(1) const u8, table[1].EntryContext);
+ switch (value_type) {
+ REG.DWORD, REG.DWORD_BIG_ENDIAN => return entry[0..4],
+ REG.QWORD => return entry[0..8],
+ else => unreachable,
+ }
+ },
+
else => unreachable,
},
else => return std.os.windows.unexpectedStatus(res),
@@ -216,11 +236,11 @@ fn detectCpuModelArm64() !*const Target.Cpu.Model {
var i: usize = 0;
while (i < cpu_count) : (i += 1) {
- const identifier = try getCpuInfoFromRegistry([]const u8, i, "Identifier");
+ const identifier = try getCpuInfoFromRegistry(i, "Identifier", REG.SZ);
parser.parseOne(identifier);
- const hex = try getCpuInfoFromRegistry(u64, i, "CP 4000");
- std.log.warn("{d} => {x}", .{ i, hex });
+ const hex = try getCpuInfoFromRegistry(i, "CP 4000", REG.QWORD);
+ std.log.warn("{d} => {x}", .{ i, std.fmt.fmtSliceHexLower(hex) });
}
return parser.finalize() orelse Target.Cpu.Model.generic(.aarch64);