Skip to content

Commit 33903d2

Browse files
Kevin Hogelandcopybara-github
Kevin Hogeland
authored andcommitted
Fix Windows developer mode symlinks
The OS version check in #13488 breaks the developer mode symlink behavior. `IsWindowsVersionOrGreater` does not work as advertised, and returns false on Windows 10 if not called from an executable with an associated application manifest declaring its compatibility for Windows 10. (Very cool, Microsoft.) The other methods of checking OS version are far more verbose and complicated, which doesn't seem warranted here. As an alternative workaround, this PR replaces the ahead-of-time version check with a retry without the flag if the function reports an invalid argument exception. @meteorcloudy Closes #13629. PiperOrigin-RevId: 382734470
1 parent 080d4ad commit 33903d2

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

src/main/native/windows/file.cc

+13-10
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,12 @@ using std::wstring;
4343
DWORD DetermineSymlinkPrivilegeFlag() {
4444
DWORD val = 0;
4545
DWORD valSize = sizeof(val);
46-
if ( // The unprivileged create flag was introduced in Windows 10 build
47-
// 14972:
48-
// https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10/
49-
!IsWindowsVersionOrGreater(10, 0, 14972)
50-
// Check if developer mode is disabled:
51-
|| RegGetValueW(
52-
HKEY_LOCAL_MACHINE,
53-
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock",
54-
L"AllowDevelopmentWithoutDevLicense", RRF_RT_DWORD, nullptr, &val,
55-
&valSize) != ERROR_SUCCESS ||
46+
// Check if developer mode is disabled
47+
if (RegGetValueW(
48+
HKEY_LOCAL_MACHINE,
49+
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock",
50+
L"AllowDevelopmentWithoutDevLicense", RRF_RT_DWORD, nullptr, &val,
51+
&valSize) != ERROR_SUCCESS ||
5652
val == 0) {
5753
return 0;
5854
}
@@ -467,6 +463,13 @@ int CreateSymlink(const wstring& symlink_name, const wstring& symlink_target,
467463

468464
if (!CreateSymbolicLinkW(name.c_str(), target.c_str(),
469465
symlinkPrivilegeFlag)) {
466+
if (GetLastError() == ERROR_INVALID_PARAMETER) {
467+
// We are on a version of Windows that does not support this flag.
468+
// Retry without the flag and return to error handling if necessary.
469+
if (CreateSymbolicLinkW(name.c_str(), target.c_str(), 0)) {
470+
return CreateSymlinkResult::kSuccess;
471+
}
472+
}
470473
*error = MakeErrorMessage(
471474
WSTR(__FILE__), __LINE__, L"CreateSymlink", symlink_target,
472475
GetLastError() == ERROR_PRIVILEGE_NOT_HELD

src/main/native/windows/file.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ bool IsDeveloperModeEnabled();
3838
DWORD DetermineSymlinkPrivilegeFlag();
3939

4040
// The flag SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE requires
41-
// developer mode to be enabled. If it is not enabled, or the current
42-
// version of Windows does not support it, do not use the flag.
43-
// The process will need to be run with elevated privileges.
41+
// developer mode to be enabled. If it is not enabled, do not use the
42+
// flag. The process will need to be run with elevated privileges.
4443
const DWORD symlinkPrivilegeFlag = DetermineSymlinkPrivilegeFlag();
4544

4645
template <typename char_type>

src/main/tools/build-runfiles-windows.cc

+8
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,14 @@ class RunfilesCreator {
336336
if (!CreateSymbolicLinkW(
337337
it.first.c_str(), it.second.c_str(),
338338
bazel::windows::symlinkPrivilegeFlag | create_dir)) {
339+
if (GetLastError() == ERROR_INVALID_PARAMETER) {
340+
// We are on a version of Windows that does not support this flag.
341+
// Retry without the flag and return to error handling if necessary.
342+
if (CreateSymbolicLinkW(it.first.c_str(), it.second.c_str(),
343+
create_dir)) {
344+
return;
345+
}
346+
}
339347
if (GetLastError() == ERROR_PRIVILEGE_NOT_HELD) {
340348
die(L"CreateSymbolicLinkW failed:\n%hs\n",
341349
"Bazel needs to create symlinks to build the runfiles tree.\n"

0 commit comments

Comments
 (0)