diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-11-27 14:13:28 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-11-28 17:07:34 +0100 |
| commit | d64d7aaac7650d79a6f5a5c5d0db6730b6a11b2c (patch) | |
| tree | de2a78212571eae6a327b7c7e2d1e6fc669cc9c2 /lib | |
| parent | 57bda6524b2dbe69c20f25e99c9b136dd0859297 (diff) | |
| download | zig-d64d7aaac7650d79a6f5a5c5d0db6730b6a11b2c.tar.gz zig-d64d7aaac7650d79a6f5a5c5d0db6730b6a11b2c.zip | |
windows: drive the registry helper with actual value set for reg entries
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/std/os/windows.zig | 56 | ||||
| -rw-r--r-- | lib/std/zig/system/windows.zig | 96 |
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); |
