Skip to content

Commit cdc0cee

Browse files
committed
WindowsSdk: Fix every registry key being opened with KEY_WOW64_32KEY
Now, an options struct is used to determine whether or not KEY_WOW64_32KEY should be set when opening a registry key.
1 parent cf8f0cd commit cdc0cee

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

lib/std/zig/WindowsSdk.zig

+25-15
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub fn find(allocator: std.mem.Allocator) error{ OutOfMemory, NotFound, PathTooL
2323
if (builtin.os.tag != .windows) return error.NotFound;
2424

2525
//note(dimenus): If this key doesn't exist, neither the Win 8 SDK nor the Win 10 SDK is installed
26-
const roots_key = RegistryWtf8.openKey(windows.HKEY_LOCAL_MACHINE, windows_kits_reg_key) catch |err| switch (err) {
26+
const roots_key = RegistryWtf8.openKey(windows.HKEY_LOCAL_MACHINE, windows_kits_reg_key, .{ .wow64_32 = true }) catch |err| switch (err) {
2727
error.KeyNotFound => return error.NotFound,
2828
};
2929
defer roots_key.closeKey();
@@ -137,11 +137,17 @@ fn iterateAndFilterByVersion(
137137
return dirs.toOwnedSlice();
138138
}
139139

140+
const OpenOptions = struct {
141+
/// Sets the KEY_WOW64_32KEY access flag.
142+
/// https://learn.microsoft.com/en-us/windows/win32/winprog64/accessing-an-alternate-registry-view
143+
wow64_32: bool = false,
144+
};
145+
140146
const RegistryWtf8 = struct {
141147
key: windows.HKEY,
142148

143149
/// Assert that `key` is valid WTF-8 string
144-
pub fn openKey(hkey: windows.HKEY, key: []const u8) error{KeyNotFound}!RegistryWtf8 {
150+
pub fn openKey(hkey: windows.HKEY, key: []const u8, options: OpenOptions) error{KeyNotFound}!RegistryWtf8 {
145151
const key_wtf16le: [:0]const u16 = key_wtf16le: {
146152
var key_wtf16le_buf: [RegistryWtf16Le.key_name_max_len]u16 = undefined;
147153
const key_wtf16le_len: usize = std.unicode.wtf8ToWtf16Le(key_wtf16le_buf[0..], key) catch |err| switch (err) {
@@ -151,7 +157,7 @@ const RegistryWtf8 = struct {
151157
break :key_wtf16le key_wtf16le_buf[0..key_wtf16le_len :0];
152158
};
153159

154-
const registry_wtf16le = try RegistryWtf16Le.openKey(hkey, key_wtf16le);
160+
const registry_wtf16le = try RegistryWtf16Le.openKey(hkey, key_wtf16le, options);
155161
return .{ .key = registry_wtf16le.key };
156162
}
157163

@@ -239,15 +245,17 @@ const RegistryWtf16Le = struct {
239245
pub const value_name_max_len = 16_383;
240246

241247
/// Under HKEY_LOCAL_MACHINE with flags:
242-
/// KEY_QUERY_VALUE, KEY_WOW64_32KEY, and KEY_ENUMERATE_SUB_KEYS.
248+
/// KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, optionally KEY_WOW64_32KEY.
243249
/// After finishing work, call `closeKey`.
244-
fn openKey(hkey: windows.HKEY, key_wtf16le: [:0]const u16) error{KeyNotFound}!RegistryWtf16Le {
250+
fn openKey(hkey: windows.HKEY, key_wtf16le: [:0]const u16, options: OpenOptions) error{KeyNotFound}!RegistryWtf16Le {
245251
var key: windows.HKEY = undefined;
252+
var access: windows.REGSAM = windows.KEY_QUERY_VALUE | windows.KEY_ENUMERATE_SUB_KEYS;
253+
if (options.wow64_32) access |= windows.KEY_WOW64_32KEY;
246254
const return_code_int: windows.HRESULT = windows.advapi32.RegOpenKeyExW(
247255
hkey,
248256
key_wtf16le,
249257
0,
250-
windows.KEY_QUERY_VALUE | windows.KEY_WOW64_32KEY | windows.KEY_ENUMERATE_SUB_KEYS,
258+
access,
251259
&key,
252260
);
253261
const return_code: windows.Win32Error = @enumFromInt(return_code_int);
@@ -484,13 +492,14 @@ pub const Installation = struct {
484492
version_key_name: []const u8,
485493
) error{ OutOfMemory, InstallationNotFound, PathTooLong, VersionTooLong }!Installation {
486494
var key_name_buf: [RegistryWtf16Le.key_name_max_len]u8 = undefined;
487-
const key = key: for ([_][]const u8{ "\\Wow6432Node", "" }) |wow6432node| {
495+
const key_name = std.fmt.bufPrint(
496+
&key_name_buf,
497+
"SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\{s}",
498+
.{version_key_name},
499+
) catch unreachable;
500+
const key = key: for ([_]bool{ true, false }) |wow6432node| {
488501
for ([_]windows.HKEY{ windows.HKEY_LOCAL_MACHINE, windows.HKEY_CURRENT_USER }) |hkey| {
489-
break :key RegistryWtf8.openKey(hkey, std.fmt.bufPrint(
490-
&key_name_buf,
491-
"SOFTWARE{s}\\Microsoft\\Microsoft SDKs\\Windows\\{s}",
492-
.{ wow6432node, version_key_name },
493-
) catch unreachable) catch |err| switch (err) {
502+
break :key RegistryWtf8.openKey(hkey, key_name, .{ .wow64_32 = wow6432node }) catch |err| switch (err) {
494503
error.KeyNotFound => return error.InstallationNotFound,
495504
};
496505
}
@@ -563,6 +572,7 @@ pub const Installation = struct {
563572
const options_key = RegistryWtf8.openKey(
564573
windows.HKEY_LOCAL_MACHINE,
565574
reg_query_as_wtf8,
575+
.{ .wow64_32 = true },
566576
) catch |err| switch (err) {
567577
error.KeyNotFound => return false,
568578
};
@@ -589,7 +599,7 @@ pub const Installation = struct {
589599
const MsvcLibDir = struct {
590600
fn findInstancesDirViaSetup(allocator: std.mem.Allocator) error{ OutOfMemory, PathNotFound }!std.fs.Dir {
591601
const vs_setup_key_path = "SOFTWARE\\Microsoft\\VisualStudio\\Setup";
592-
const vs_setup_key = RegistryWtf8.openKey(windows.HKEY_LOCAL_MACHINE, vs_setup_key_path) catch |err| switch (err) {
602+
const vs_setup_key = RegistryWtf8.openKey(windows.HKEY_LOCAL_MACHINE, vs_setup_key_path, .{}) catch |err| switch (err) {
593603
error.KeyNotFound => return error.PathNotFound,
594604
};
595605
defer vs_setup_key.closeKey();
@@ -614,7 +624,7 @@ const MsvcLibDir = struct {
614624

615625
fn findInstancesDirViaCLSID(allocator: std.mem.Allocator) error{ OutOfMemory, PathNotFound }!std.fs.Dir {
616626
const setup_configuration_clsid = "{177f0c4a-1cd3-4de7-a32c-71dbbb9fa36d}";
617-
const setup_config_key = RegistryWtf8.openKey(windows.HKEY_CLASSES_ROOT, "CLSID\\" ++ setup_configuration_clsid) catch |err| switch (err) {
627+
const setup_config_key = RegistryWtf8.openKey(windows.HKEY_CLASSES_ROOT, "CLSID\\" ++ setup_configuration_clsid, .{}) catch |err| switch (err) {
618628
error.KeyNotFound => return error.PathNotFound,
619629
};
620630
defer setup_config_key.closeKey();
@@ -941,7 +951,7 @@ const MsvcLibDir = struct {
941951
}
942952
}
943953

944-
const vs7_key = RegistryWtf8.openKey(windows.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7") catch return error.PathNotFound;
954+
const vs7_key = RegistryWtf8.openKey(windows.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7", .{ .wow64_32 = true }) catch return error.PathNotFound;
945955
defer vs7_key.closeKey();
946956
try_vs7_key: {
947957
const path_maybe_with_trailing_slash = vs7_key.getString(allocator, "", "14.0") catch |err| switch (err) {

0 commit comments

Comments
 (0)