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.
|
/// If the types do not match, the call fails.
|
||||||
pub const RTL_QUERY_REGISTRY_TYPECHECK = 0x00000100;
|
pub const RTL_QUERY_REGISTRY_TYPECHECK = 0x00000100;
|
||||||
|
|
||||||
/// No value type
|
pub const REG = struct {
|
||||||
pub const REG_NONE = 0;
|
/// No value type
|
||||||
/// Unicode nul terminated string
|
pub const NONE: ULONG = 0;
|
||||||
pub const REG_SZ = 1;
|
/// Unicode nul terminated string
|
||||||
/// Unicode nul terminated string (with environment variable references)
|
pub const SZ: ULONG = 1;
|
||||||
pub const REG_EXPAND_SZ = 2;
|
/// Unicode nul terminated string (with environment variable references)
|
||||||
/// Free form binary
|
pub const EXPAND_SZ: ULONG = 2;
|
||||||
pub const REG_BINARY = 3;
|
/// Free form binary
|
||||||
/// 32-bit number
|
pub const BINARY: ULONG = 3;
|
||||||
pub const REG_DWORD = 4;
|
/// 32-bit number
|
||||||
/// 32-bit number (same as REG_DWORD)
|
pub const DWORD: ULONG = 4;
|
||||||
pub const REG_DWORD_LITTLE_ENDIAN = 4;
|
/// 32-bit number (same as REG_DWORD)
|
||||||
/// 32-bit number
|
pub const DWORD_LITTLE_ENDIAN: ULONG = 4;
|
||||||
pub const REG_DWORD_BIG_ENDIAN = 5;
|
/// 32-bit number
|
||||||
/// Symbolic Link (unicode)
|
pub const DWORD_BIG_ENDIAN: ULONG = 5;
|
||||||
pub const REG_LINK = 6;
|
/// Symbolic Link (unicode)
|
||||||
/// Multiple Unicode strings
|
pub const LINK: ULONG = 6;
|
||||||
pub const REG_MULTI_SZ = 7;
|
/// Multiple Unicode strings
|
||||||
/// Resource list in the resource map
|
pub const MULTI_SZ: ULONG = 7;
|
||||||
pub const REG_RESOURCE_LIST = 8;
|
/// Resource list in the resource map
|
||||||
/// Resource list in the hardware description
|
pub const RESOURCE_LIST: ULONG = 8;
|
||||||
pub const REG_FULL_RESOURCE_DESCRIPTOR = 9;
|
/// Resource list in the hardware description
|
||||||
pub const REG_RESOURCE_REQUIREMENTS_LIST = 10;
|
pub const FULL_RESOURCE_DESCRIPTOR: ULONG = 9;
|
||||||
/// 64-bit number
|
pub const RESOURCE_REQUIREMENTS_LIST: ULONG = 10;
|
||||||
pub const REG_QWORD = 11;
|
/// 64-bit number
|
||||||
/// 64-bit number (same as REG_QWORD)
|
pub const QWORD: ULONG = 11;
|
||||||
pub const REG_QWORD_LITTLE_ENDIAN = 11;
|
/// 64-bit number (same as REG_QWORD)
|
||||||
|
pub const QWORD_LITTLE_ENDIAN: ULONG = 11;
|
||||||
|
};
|
||||||
|
|
||||||
pub const FILE_NOTIFY_INFORMATION = extern struct {
|
pub const FILE_NOTIFY_INFORMATION = extern struct {
|
||||||
NextEntryOffset: DWORD,
|
NextEntryOffset: DWORD,
|
||||||
|
|||||||
@ -5,6 +5,7 @@ const Target = std.Target;
|
|||||||
|
|
||||||
pub const WindowsVersion = std.Target.Os.WindowsVersion;
|
pub const WindowsVersion = std.Target.Os.WindowsVersion;
|
||||||
pub const PF = std.os.windows.PF;
|
pub const PF = std.os.windows.PF;
|
||||||
|
pub const REG = std.os.windows.REG;
|
||||||
pub const IsProcessorFeaturePresent = std.os.windows.IsProcessorFeaturePresent;
|
pub const IsProcessorFeaturePresent = std.os.windows.IsProcessorFeaturePresent;
|
||||||
|
|
||||||
/// Returns the highest known WindowsVersion deduced from reported runtime information.
|
/// 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);
|
const key_name = std.unicode.utf8ToUtf16LeStringLiteral(key);
|
||||||
|
|
||||||
// Originally, I wanted to issue a single call with a more complex table structure such that we
|
// 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");
|
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
|
// Technically, a registry value can be as long as 1MB. However, MS recommends storing
|
||||||
// values larger than 2048 in a file rather than directly in the registry, and since we
|
// 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.
|
// 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
|
// 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: {
|
const ctx: *anyopaque = blk: {
|
||||||
switch (@typeInfo(T)) {
|
switch (value_type) {
|
||||||
.Int => |int| {
|
REG.NONE => unreachable,
|
||||||
const bits = int.bits;
|
|
||||||
var buf: [bits * 8]u8 = undefined;
|
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;
|
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;
|
REG.QWORD => {
|
||||||
var unicode = std.os.windows.UNICODE_STRING{
|
var buf: [8]u8 = undefined;
|
||||||
.Length = buf.len * 2,
|
break :blk &buf;
|
||||||
.MaximumLength = buf.len * 2,
|
|
||||||
.Buffer = &buf,
|
|
||||||
};
|
|
||||||
break :blk &unicode;
|
|
||||||
},
|
|
||||||
else => @compileError("Unsupported type " ++ @typeName(T) ++ " as registry value"),
|
|
||||||
},
|
},
|
||||||
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,
|
.Flags = std.os.windows.RTL_QUERY_REGISTRY_SUBKEY | std.os.windows.RTL_QUERY_REGISTRY_REQUIRED,
|
||||||
.Name = subkey[0..subkey_len :0],
|
.Name = subkey[0..subkey_len :0],
|
||||||
.EntryContext = null,
|
.EntryContext = null,
|
||||||
.DefaultType = std.os.windows.REG_NONE,
|
.DefaultType = REG.NONE,
|
||||||
.DefaultData = null,
|
.DefaultData = null,
|
||||||
.DefaultLength = 0,
|
.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,
|
.Flags = std.os.windows.RTL_QUERY_REGISTRY_DIRECT | std.os.windows.RTL_QUERY_REGISTRY_REQUIRED,
|
||||||
.Name = @intToPtr([*:0]u16, @ptrToInt(key_name)),
|
.Name = @intToPtr([*:0]u16, @ptrToInt(key_name)),
|
||||||
.EntryContext = ctx,
|
.EntryContext = ctx,
|
||||||
.DefaultType = std.os.windows.REG_NONE,
|
.DefaultType = REG.NONE,
|
||||||
.DefaultData = null,
|
.DefaultData = null,
|
||||||
.DefaultLength = 0,
|
.DefaultLength = 0,
|
||||||
};
|
};
|
||||||
@ -186,17 +192,31 @@ fn getCpuInfoFromRegistry(comptime T: type, core: usize, comptime key: []const u
|
|||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
switch (res) {
|
switch (res) {
|
||||||
.SUCCESS => switch (@typeInfo(T)) {
|
.SUCCESS => switch (value_type) {
|
||||||
.Int => {
|
REG.NONE => unreachable,
|
||||||
const entry = @ptrCast(*align(1) const T, table[1].EntryContext);
|
|
||||||
return entry.*;
|
REG.SZ,
|
||||||
},
|
REG.EXPAND_SZ,
|
||||||
.Pointer => {
|
REG.MULTI_SZ,
|
||||||
|
=> {
|
||||||
const entry = @ptrCast(*align(1) const std.os.windows.UNICODE_STRING, table[1].EntryContext);
|
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]);
|
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 => unreachable,
|
||||||
},
|
},
|
||||||
else => return std.os.windows.unexpectedStatus(res),
|
else => return std.os.windows.unexpectedStatus(res),
|
||||||
@ -216,11 +236,11 @@ fn detectCpuModelArm64() !*const Target.Cpu.Model {
|
|||||||
|
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (i < cpu_count) : (i += 1) {
|
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);
|
parser.parseOne(identifier);
|
||||||
|
|
||||||
const hex = try getCpuInfoFromRegistry(u64, i, "CP 4000");
|
const hex = try getCpuInfoFromRegistry(i, "CP 4000", REG.QWORD);
|
||||||
std.log.warn("{d} => {x}", .{ i, hex });
|
std.log.warn("{d} => {x}", .{ i, std.fmt.fmtSliceHexLower(hex) });
|
||||||
}
|
}
|
||||||
|
|
||||||
return parser.finalize() orelse Target.Cpu.Model.generic(.aarch64);
|
return parser.finalize() orelse Target.Cpu.Model.generic(.aarch64);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user