summaryrefslogtreecommitdiffstats
path: root/platform_utils_win32.py
diff options
context:
space:
mode:
authorDavid Pursehouse <dpursehouse@collab.net>2017-08-30 10:24:03 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2017-08-30 10:24:03 +0000
commitd1ebc89a083f2966f8c65246bb63e2deaadfab62 (patch)
treecd6bd047ba2c7b83a25ba045a48efa95393f7fbe /platform_utils_win32.py
parent9ead97bb51f5b1ad1d0a45e0c5442f15e1e38fd7 (diff)
parentad1abcb556bfff2744928a8f29d216aee43fdbe3 (diff)
downloadgit-repo-d1ebc89a083f2966f8c65246bb63e2deaadfab62.tar.gz
Merge changes from topic "windows-support"
* changes: Port os.rename calls to work on Windows Workaround shutil.rmtree limitation on Windows Add support for creating symbolic links on Windows Make "git command" and "forall" work on Windows
Diffstat (limited to 'platform_utils_win32.py')
-rw-r--r--platform_utils_win32.py63
1 files changed, 63 insertions, 0 deletions
diff --git a/platform_utils_win32.py b/platform_utils_win32.py
new file mode 100644
index 00000000..02fb013a
--- /dev/null
+++ b/platform_utils_win32.py
@@ -0,0 +1,63 @@
1#
2# Copyright (C) 2016 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import errno
17
18from ctypes import WinDLL, get_last_error, FormatError, WinError
19from ctypes.wintypes import BOOL, LPCWSTR, DWORD
20
21kernel32 = WinDLL('kernel32', use_last_error=True)
22
23# Win32 error codes
24ERROR_SUCCESS = 0
25ERROR_PRIVILEGE_NOT_HELD = 1314
26
27# Win32 API entry points
28CreateSymbolicLinkW = kernel32.CreateSymbolicLinkW
29CreateSymbolicLinkW.restype = BOOL
30CreateSymbolicLinkW.argtypes = (LPCWSTR, # lpSymlinkFileName In
31 LPCWSTR, # lpTargetFileName In
32 DWORD) # dwFlags In
33
34# Symbolic link creation flags
35SYMBOLIC_LINK_FLAG_FILE = 0x00
36SYMBOLIC_LINK_FLAG_DIRECTORY = 0x01
37
38
39def create_filesymlink(source, link_name):
40 """Creates a Windows file symbolic link source pointing to link_name."""
41 _create_symlink(source, link_name, SYMBOLIC_LINK_FLAG_FILE)
42
43
44def create_dirsymlink(source, link_name):
45 """Creates a Windows directory symbolic link source pointing to link_name.
46 """
47 _create_symlink(source, link_name, SYMBOLIC_LINK_FLAG_DIRECTORY)
48
49
50def _create_symlink(source, link_name, dwFlags):
51 # Note: Win32 documentation for CreateSymbolicLink is incorrect.
52 # On success, the function returns "1".
53 # On error, the function returns some random value (e.g. 1280).
54 # The best bet seems to use "GetLastError" and check for error/success.
55 CreateSymbolicLinkW(link_name, source, dwFlags)
56 code = get_last_error()
57 if code != ERROR_SUCCESS:
58 error_desc = FormatError(code).strip()
59 if code == ERROR_PRIVILEGE_NOT_HELD:
60 raise OSError(errno.EPERM, error_desc, link_name)
61 error_desc = 'Error creating symbolic link %s: %s'.format(
62 link_name, error_desc)
63 raise WinError(code, error_desc)