@@ -23,7 +23,7 @@ pub fn find(allocator: std.mem.Allocator) error{ OutOfMemory, NotFound, PathTooL
23
23
if (builtin .os .tag != .windows ) return error .NotFound ;
24
24
25
25
//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 ) {
27
27
error .KeyNotFound = > return error .NotFound ,
28
28
};
29
29
defer roots_key .closeKey ();
@@ -137,11 +137,17 @@ fn iterateAndFilterByVersion(
137
137
return dirs .toOwnedSlice ();
138
138
}
139
139
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
+
140
146
const RegistryWtf8 = struct {
141
147
key : windows.HKEY ,
142
148
143
149
/// 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 {
145
151
const key_wtf16le : [:0 ]const u16 = key_wtf16le : {
146
152
var key_wtf16le_buf : [RegistryWtf16Le .key_name_max_len ]u16 = undefined ;
147
153
const key_wtf16le_len : usize = std .unicode .wtf8ToWtf16Le (key_wtf16le_buf [0.. ], key ) catch | err | switch (err ) {
@@ -151,7 +157,7 @@ const RegistryWtf8 = struct {
151
157
break :key_wtf16le key_wtf16le_buf [0.. key_wtf16le_len :0 ];
152
158
};
153
159
154
- const registry_wtf16le = try RegistryWtf16Le .openKey (hkey , key_wtf16le );
160
+ const registry_wtf16le = try RegistryWtf16Le .openKey (hkey , key_wtf16le , options );
155
161
return .{ .key = registry_wtf16le .key };
156
162
}
157
163
@@ -239,15 +245,17 @@ const RegistryWtf16Le = struct {
239
245
pub const value_name_max_len = 16_383 ;
240
246
241
247
/// 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 .
243
249
/// 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 {
245
251
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 ;
246
254
const return_code_int : windows.HRESULT = windows .advapi32 .RegOpenKeyExW (
247
255
hkey ,
248
256
key_wtf16le ,
249
257
0 ,
250
- windows . KEY_QUERY_VALUE | windows . KEY_WOW64_32KEY | windows . KEY_ENUMERATE_SUB_KEYS ,
258
+ access ,
251
259
& key ,
252
260
);
253
261
const return_code : windows.Win32Error = @enumFromInt (return_code_int );
@@ -484,13 +492,14 @@ pub const Installation = struct {
484
492
version_key_name : []const u8 ,
485
493
) error { OutOfMemory , InstallationNotFound , PathTooLong , VersionTooLong }! Installation {
486
494
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 | {
488
501
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 ) {
494
503
error .KeyNotFound = > return error .InstallationNotFound ,
495
504
};
496
505
}
@@ -563,6 +572,7 @@ pub const Installation = struct {
563
572
const options_key = RegistryWtf8 .openKey (
564
573
windows .HKEY_LOCAL_MACHINE ,
565
574
reg_query_as_wtf8 ,
575
+ .{ .wow64_32 = true },
566
576
) catch | err | switch (err ) {
567
577
error .KeyNotFound = > return false ,
568
578
};
@@ -589,7 +599,7 @@ pub const Installation = struct {
589
599
const MsvcLibDir = struct {
590
600
fn findInstancesDirViaSetup (allocator : std.mem.Allocator ) error { OutOfMemory , PathNotFound }! std.fs.Dir {
591
601
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 ) {
593
603
error .KeyNotFound = > return error .PathNotFound ,
594
604
};
595
605
defer vs_setup_key .closeKey ();
@@ -614,7 +624,7 @@ const MsvcLibDir = struct {
614
624
615
625
fn findInstancesDirViaCLSID (allocator : std.mem.Allocator ) error { OutOfMemory , PathNotFound }! std.fs.Dir {
616
626
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 ) {
618
628
error .KeyNotFound = > return error .PathNotFound ,
619
629
};
620
630
defer setup_config_key .closeKey ();
@@ -941,7 +951,7 @@ const MsvcLibDir = struct {
941
951
}
942
952
}
943
953
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 ;
945
955
defer vs7_key .closeKey ();
946
956
try_vs7_key : {
947
957
const path_maybe_with_trailing_slash = vs7_key .getString (allocator , "" , "14.0" ) catch | err | switch (err ) {
0 commit comments