diff options
Diffstat (limited to 'platform_utils_win32.py')
| -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): |
