mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 11:13:08 +00:00
windows: drive the registry helper with actual value set for reg entries
This commit is contained in:
parent
57bda6524b
commit
d64d7aaac7
@ -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,
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user