diff --git a/src/main/native/windows/file.cc b/src/main/native/windows/file.cc index eb23f43f689624..76c7a5e948ccca 100644 --- a/src/main/native/windows/file.cc +++ b/src/main/native/windows/file.cc @@ -43,16 +43,12 @@ using std::wstring; DWORD DetermineSymlinkPrivilegeFlag() { DWORD val = 0; DWORD valSize = sizeof(val); - if ( // The unprivileged create flag was introduced in Windows 10 build - // 14972: - // https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10/ - !IsWindowsVersionOrGreater(10, 0, 14972) - // Check if developer mode is disabled: - || RegGetValueW( - HKEY_LOCAL_MACHINE, - L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock", - L"AllowDevelopmentWithoutDevLicense", RRF_RT_DWORD, nullptr, &val, - &valSize) != ERROR_SUCCESS || + // Check if developer mode is disabled + if (RegGetValueW( + HKEY_LOCAL_MACHINE, + L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock", + L"AllowDevelopmentWithoutDevLicense", RRF_RT_DWORD, nullptr, &val, + &valSize) != ERROR_SUCCESS || val == 0) { return 0; } @@ -467,6 +463,13 @@ int CreateSymlink(const wstring& symlink_name, const wstring& symlink_target, if (!CreateSymbolicLinkW(name.c_str(), target.c_str(), symlinkPrivilegeFlag)) { + if (GetLastError() == ERROR_INVALID_PARAMETER) { + // We are on a version of Windows that does not support this flag. + // Retry without the flag and return to error handling if necessary. + if (CreateSymbolicLinkW(name.c_str(), target.c_str(), 0)) { + return CreateSymlinkResult::kSuccess; + } + } *error = MakeErrorMessage( WSTR(__FILE__), __LINE__, L"CreateSymlink", symlink_target, GetLastError() == ERROR_PRIVILEGE_NOT_HELD diff --git a/src/main/native/windows/file.h b/src/main/native/windows/file.h index 421d97112e586f..590137fc842107 100644 --- a/src/main/native/windows/file.h +++ b/src/main/native/windows/file.h @@ -38,9 +38,8 @@ bool IsDeveloperModeEnabled(); DWORD DetermineSymlinkPrivilegeFlag(); // The flag SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE requires -// developer mode to be enabled. If it is not enabled, or the current -// version of Windows does not support it, do not use the flag. -// The process will need to be run with elevated privileges. +// developer mode to be enabled. If it is not enabled, do not use the +// flag. The process will need to be run with elevated privileges. const DWORD symlinkPrivilegeFlag = DetermineSymlinkPrivilegeFlag(); template diff --git a/src/main/tools/build-runfiles-windows.cc b/src/main/tools/build-runfiles-windows.cc index f9498b374261ae..a773e841e0ef38 100644 --- a/src/main/tools/build-runfiles-windows.cc +++ b/src/main/tools/build-runfiles-windows.cc @@ -336,6 +336,14 @@ class RunfilesCreator { if (!CreateSymbolicLinkW( it.first.c_str(), it.second.c_str(), bazel::windows::symlinkPrivilegeFlag | create_dir)) { + if (GetLastError() == ERROR_INVALID_PARAMETER) { + // We are on a version of Windows that does not support this flag. + // Retry without the flag and return to error handling if necessary. + if (CreateSymbolicLinkW(it.first.c_str(), it.second.c_str(), + create_dir)) { + return; + } + } if (GetLastError() == ERROR_PRIVILEGE_NOT_HELD) { die(L"CreateSymbolicLinkW failed:\n%hs\n", "Bazel needs to create symlinks to build the runfiles tree.\n"