Fix wscript not being able to create symlinks on Windows 10 with Developer Mode enabled when Python 3 is used.

This commit is contained in:
Daan De Meyer 2018-02-05 19:57:50 +01:00 committed by Jacob Dufault
parent 1a82f1f113
commit a3c374d368

50
wscript
View File

@ -37,32 +37,30 @@ elif sys.platform == 'win32':
from waflib.Tools.compiler_cxx import cxx_compiler from waflib.Tools.compiler_cxx import cxx_compiler
cxx_compiler['linux'] = ['clang++', 'g++'] cxx_compiler['linux'] = ['clang++', 'g++']
if sys.version_info < (3, 0): # Creating symbolic link on Windows requires a special priviledge SeCreateSymboliclinkPrivilege,
if sys.platform == 'win32': # which an non-elevated process lacks. Starting with Windows 10 build 14972, this got relaxed
kdll = ctypes.windll.kernel32 # when Developer Mode is enabled. Triggering this new behaviour requires a new flag.
def symlink(source, link_name, target_is_directory=False): SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2
# SYMBOLIC_LINK_FLAG_DIRECTORY: 0x1
SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2 # Python 2 has no symlink function and Python 3's symlink function does not allow creation of
flags = int(target_is_directory) # symlinks without admin rights (even when Developer Mode is enabled) so we define our own
ret = kdll.CreateSymbolicLinkA(link_name, source, flags) # symlink function when on Windows.
if ret == 0: if sys.platform == 'win32':
err = ctypes.WinError() kdll = ctypes.windll.kernel32
ERROR_PRIVILEGE_NOT_HELD = 1314 def symlink(source, link_name, target_is_directory=False):
# Creating symbolic link on Windows requires a special priviledge SeCreateSymboliclinkPrivilege, # SYMBOLIC_LINK_FLAG_DIRECTORY: 0x1
# which an non-elevated process lacks. Starting with Windows 10 build 14972, this got relaxed flags = int(target_is_directory) | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
# when Developer Mode is enabled. Triggering this new behaviour requires a new flag. Try again.
if err[0] == ERROR_PRIVILEGE_NOT_HELD: # Use unicode version (W suffix) of Windows symbolic link function and convert strings to
flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE # unicode if Python 2 is used (strings are unicode by default in Python 3).
ret = kdll.CreateSymbolicLinkA(link_name, source, flags) if sys.version_info < (3, 0):
if ret != 0: ret = kdll.CreateSymbolicLinkW(unicode(link_name), unicode(source), flags)
return else:
err = ctypes.WinError() ret = kdll.CreateSymbolicLinkW(link_name, source, flags)
raise err
else: if ret == 0:
# Python 3 compatibility err = ctypes.WinError()
real_symlink = os.symlink raise err
def symlink(source, link_name, target_is_directory=False):
return real_symlink(source, link_name)
os.symlink = symlink os.symlink = symlink
# There is a null pointer dereference issue in tools/libclang/CXIndexDataConsumer.cpp handleReference. # There is a null pointer dereference issue in tools/libclang/CXIndexDataConsumer.cpp handleReference.