diff options
-rw-r--r-- | platform_utils_win32.py | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/platform_utils_win32.py b/platform_utils_win32.py index fe76b3d6..a6431216 100644 --- a/platform_utils_win32.py +++ b/platform_utils_win32.py | |||
@@ -41,6 +41,8 @@ CreateSymbolicLinkW.argtypes = (LPCWSTR, # lpSymlinkFileName In | |||
41 | # Symbolic link creation flags | 41 | # Symbolic link creation flags |
42 | SYMBOLIC_LINK_FLAG_FILE = 0x00 | 42 | SYMBOLIC_LINK_FLAG_FILE = 0x00 |
43 | SYMBOLIC_LINK_FLAG_DIRECTORY = 0x01 | 43 | SYMBOLIC_LINK_FLAG_DIRECTORY = 0x01 |
44 | # symlink support for CreateSymbolicLink() starting with Windows 10 (1703, v10.0.14972) | ||
45 | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x02 | ||
44 | 46 | ||
45 | GetFileAttributesW = kernel32.GetFileAttributesW | 47 | GetFileAttributesW = kernel32.GetFileAttributesW |
46 | GetFileAttributesW.restype = DWORD | 48 | GetFileAttributesW.restype = DWORD |
@@ -147,15 +149,21 @@ def _create_symlink(source, link_name, dwFlags): | |||
147 | # On success, the function returns "1". | 149 | # On success, the function returns "1". |
148 | # On error, the function returns some random value (e.g. 1280). | 150 | # On error, the function returns some random value (e.g. 1280). |
149 | # The best bet seems to use "GetLastError" and check for error/success. | 151 | # The best bet seems to use "GetLastError" and check for error/success. |
150 | CreateSymbolicLinkW(link_name, source, dwFlags) | 152 | CreateSymbolicLinkW(link_name, source, dwFlags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) |
151 | code = get_last_error() | 153 | code = get_last_error() |
152 | if code != ERROR_SUCCESS: | 154 | if code != ERROR_SUCCESS: |
153 | error_desc = FormatError(code).strip() | 155 | # See https://github.com/golang/go/pull/24307/files#diff-b87bc12e4da2497308f9ef746086e4f0 |
154 | if code == ERROR_PRIVILEGE_NOT_HELD: | 156 | # "the unprivileged create flag is unsupported below Windows 10 (1703, v10.0.14972). |
155 | raise OSError(errno.EPERM, error_desc, link_name) | 157 | # retry without it." |
156 | _raise_winerror( | 158 | CreateSymbolicLinkW(link_name, source, dwFlags) |
157 | code, | 159 | code = get_last_error() |
158 | 'Error creating symbolic link \"%s\"'.format(link_name)) | 160 | if code != ERROR_SUCCESS: |
161 | error_desc = FormatError(code).strip() | ||
162 | if code == ERROR_PRIVILEGE_NOT_HELD: | ||
163 | raise OSError(errno.EPERM, error_desc, link_name) | ||
164 | _raise_winerror( | ||
165 | code, | ||
166 | 'Error creating symbolic link \"%s\"'.format(link_name)) | ||
159 | 167 | ||
160 | 168 | ||
161 | def islink(path): | 169 | def islink(path): |