##// END OF EJS Templates
util: disinfect lookup_reg strings (issue1126)...
Matt Mackall -
r6880:892806b3 default
parent child Browse files
Show More
@@ -1,371 +1,367
1 # util_win32.py - utility functions that use win32 API
1 # util_win32.py - utility functions that use win32 API
2 #
2 #
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of
6 # This software may be used and distributed according to the terms of
7 # the GNU General Public License, incorporated herein by reference.
7 # the GNU General Public License, incorporated herein by reference.
8
8
9 # Mark Hammond's win32all package allows better functionality on
9 # Mark Hammond's win32all package allows better functionality on
10 # Windows. this module overrides definitions in util.py. if not
10 # Windows. this module overrides definitions in util.py. if not
11 # available, import of this module will fail, and generic code will be
11 # available, import of this module will fail, and generic code will be
12 # used.
12 # used.
13
13
14 import win32api
14 import win32api
15
15
16 import errno, os, sys, pywintypes, win32con, win32file, win32process
16 import errno, os, sys, pywintypes, win32con, win32file, win32process
17 import cStringIO, winerror
17 import cStringIO, winerror
18 import osutil
18 import osutil
19 from win32com.shell import shell,shellcon
19 from win32com.shell import shell,shellcon
20
20
21 class WinError:
21 class WinError:
22 winerror_map = {
22 winerror_map = {
23 winerror.ERROR_ACCESS_DENIED: errno.EACCES,
23 winerror.ERROR_ACCESS_DENIED: errno.EACCES,
24 winerror.ERROR_ACCOUNT_DISABLED: errno.EACCES,
24 winerror.ERROR_ACCOUNT_DISABLED: errno.EACCES,
25 winerror.ERROR_ACCOUNT_RESTRICTION: errno.EACCES,
25 winerror.ERROR_ACCOUNT_RESTRICTION: errno.EACCES,
26 winerror.ERROR_ALREADY_ASSIGNED: errno.EBUSY,
26 winerror.ERROR_ALREADY_ASSIGNED: errno.EBUSY,
27 winerror.ERROR_ALREADY_EXISTS: errno.EEXIST,
27 winerror.ERROR_ALREADY_EXISTS: errno.EEXIST,
28 winerror.ERROR_ARITHMETIC_OVERFLOW: errno.ERANGE,
28 winerror.ERROR_ARITHMETIC_OVERFLOW: errno.ERANGE,
29 winerror.ERROR_BAD_COMMAND: errno.EIO,
29 winerror.ERROR_BAD_COMMAND: errno.EIO,
30 winerror.ERROR_BAD_DEVICE: errno.ENODEV,
30 winerror.ERROR_BAD_DEVICE: errno.ENODEV,
31 winerror.ERROR_BAD_DRIVER_LEVEL: errno.ENXIO,
31 winerror.ERROR_BAD_DRIVER_LEVEL: errno.ENXIO,
32 winerror.ERROR_BAD_EXE_FORMAT: errno.ENOEXEC,
32 winerror.ERROR_BAD_EXE_FORMAT: errno.ENOEXEC,
33 winerror.ERROR_BAD_FORMAT: errno.ENOEXEC,
33 winerror.ERROR_BAD_FORMAT: errno.ENOEXEC,
34 winerror.ERROR_BAD_LENGTH: errno.EINVAL,
34 winerror.ERROR_BAD_LENGTH: errno.EINVAL,
35 winerror.ERROR_BAD_PATHNAME: errno.ENOENT,
35 winerror.ERROR_BAD_PATHNAME: errno.ENOENT,
36 winerror.ERROR_BAD_PIPE: errno.EPIPE,
36 winerror.ERROR_BAD_PIPE: errno.EPIPE,
37 winerror.ERROR_BAD_UNIT: errno.ENODEV,
37 winerror.ERROR_BAD_UNIT: errno.ENODEV,
38 winerror.ERROR_BAD_USERNAME: errno.EINVAL,
38 winerror.ERROR_BAD_USERNAME: errno.EINVAL,
39 winerror.ERROR_BROKEN_PIPE: errno.EPIPE,
39 winerror.ERROR_BROKEN_PIPE: errno.EPIPE,
40 winerror.ERROR_BUFFER_OVERFLOW: errno.ENAMETOOLONG,
40 winerror.ERROR_BUFFER_OVERFLOW: errno.ENAMETOOLONG,
41 winerror.ERROR_BUSY: errno.EBUSY,
41 winerror.ERROR_BUSY: errno.EBUSY,
42 winerror.ERROR_BUSY_DRIVE: errno.EBUSY,
42 winerror.ERROR_BUSY_DRIVE: errno.EBUSY,
43 winerror.ERROR_CALL_NOT_IMPLEMENTED: errno.ENOSYS,
43 winerror.ERROR_CALL_NOT_IMPLEMENTED: errno.ENOSYS,
44 winerror.ERROR_CANNOT_MAKE: errno.EACCES,
44 winerror.ERROR_CANNOT_MAKE: errno.EACCES,
45 winerror.ERROR_CANTOPEN: errno.EIO,
45 winerror.ERROR_CANTOPEN: errno.EIO,
46 winerror.ERROR_CANTREAD: errno.EIO,
46 winerror.ERROR_CANTREAD: errno.EIO,
47 winerror.ERROR_CANTWRITE: errno.EIO,
47 winerror.ERROR_CANTWRITE: errno.EIO,
48 winerror.ERROR_CRC: errno.EIO,
48 winerror.ERROR_CRC: errno.EIO,
49 winerror.ERROR_CURRENT_DIRECTORY: errno.EACCES,
49 winerror.ERROR_CURRENT_DIRECTORY: errno.EACCES,
50 winerror.ERROR_DEVICE_IN_USE: errno.EBUSY,
50 winerror.ERROR_DEVICE_IN_USE: errno.EBUSY,
51 winerror.ERROR_DEV_NOT_EXIST: errno.ENODEV,
51 winerror.ERROR_DEV_NOT_EXIST: errno.ENODEV,
52 winerror.ERROR_DIRECTORY: errno.EINVAL,
52 winerror.ERROR_DIRECTORY: errno.EINVAL,
53 winerror.ERROR_DIR_NOT_EMPTY: errno.ENOTEMPTY,
53 winerror.ERROR_DIR_NOT_EMPTY: errno.ENOTEMPTY,
54 winerror.ERROR_DISK_CHANGE: errno.EIO,
54 winerror.ERROR_DISK_CHANGE: errno.EIO,
55 winerror.ERROR_DISK_FULL: errno.ENOSPC,
55 winerror.ERROR_DISK_FULL: errno.ENOSPC,
56 winerror.ERROR_DRIVE_LOCKED: errno.EBUSY,
56 winerror.ERROR_DRIVE_LOCKED: errno.EBUSY,
57 winerror.ERROR_ENVVAR_NOT_FOUND: errno.EINVAL,
57 winerror.ERROR_ENVVAR_NOT_FOUND: errno.EINVAL,
58 winerror.ERROR_EXE_MARKED_INVALID: errno.ENOEXEC,
58 winerror.ERROR_EXE_MARKED_INVALID: errno.ENOEXEC,
59 winerror.ERROR_FILENAME_EXCED_RANGE: errno.ENAMETOOLONG,
59 winerror.ERROR_FILENAME_EXCED_RANGE: errno.ENAMETOOLONG,
60 winerror.ERROR_FILE_EXISTS: errno.EEXIST,
60 winerror.ERROR_FILE_EXISTS: errno.EEXIST,
61 winerror.ERROR_FILE_INVALID: errno.ENODEV,
61 winerror.ERROR_FILE_INVALID: errno.ENODEV,
62 winerror.ERROR_FILE_NOT_FOUND: errno.ENOENT,
62 winerror.ERROR_FILE_NOT_FOUND: errno.ENOENT,
63 winerror.ERROR_GEN_FAILURE: errno.EIO,
63 winerror.ERROR_GEN_FAILURE: errno.EIO,
64 winerror.ERROR_HANDLE_DISK_FULL: errno.ENOSPC,
64 winerror.ERROR_HANDLE_DISK_FULL: errno.ENOSPC,
65 winerror.ERROR_INSUFFICIENT_BUFFER: errno.ENOMEM,
65 winerror.ERROR_INSUFFICIENT_BUFFER: errno.ENOMEM,
66 winerror.ERROR_INVALID_ACCESS: errno.EACCES,
66 winerror.ERROR_INVALID_ACCESS: errno.EACCES,
67 winerror.ERROR_INVALID_ADDRESS: errno.EFAULT,
67 winerror.ERROR_INVALID_ADDRESS: errno.EFAULT,
68 winerror.ERROR_INVALID_BLOCK: errno.EFAULT,
68 winerror.ERROR_INVALID_BLOCK: errno.EFAULT,
69 winerror.ERROR_INVALID_DATA: errno.EINVAL,
69 winerror.ERROR_INVALID_DATA: errno.EINVAL,
70 winerror.ERROR_INVALID_DRIVE: errno.ENODEV,
70 winerror.ERROR_INVALID_DRIVE: errno.ENODEV,
71 winerror.ERROR_INVALID_EXE_SIGNATURE: errno.ENOEXEC,
71 winerror.ERROR_INVALID_EXE_SIGNATURE: errno.ENOEXEC,
72 winerror.ERROR_INVALID_FLAGS: errno.EINVAL,
72 winerror.ERROR_INVALID_FLAGS: errno.EINVAL,
73 winerror.ERROR_INVALID_FUNCTION: errno.ENOSYS,
73 winerror.ERROR_INVALID_FUNCTION: errno.ENOSYS,
74 winerror.ERROR_INVALID_HANDLE: errno.EBADF,
74 winerror.ERROR_INVALID_HANDLE: errno.EBADF,
75 winerror.ERROR_INVALID_LOGON_HOURS: errno.EACCES,
75 winerror.ERROR_INVALID_LOGON_HOURS: errno.EACCES,
76 winerror.ERROR_INVALID_NAME: errno.EINVAL,
76 winerror.ERROR_INVALID_NAME: errno.EINVAL,
77 winerror.ERROR_INVALID_OWNER: errno.EINVAL,
77 winerror.ERROR_INVALID_OWNER: errno.EINVAL,
78 winerror.ERROR_INVALID_PARAMETER: errno.EINVAL,
78 winerror.ERROR_INVALID_PARAMETER: errno.EINVAL,
79 winerror.ERROR_INVALID_PASSWORD: errno.EPERM,
79 winerror.ERROR_INVALID_PASSWORD: errno.EPERM,
80 winerror.ERROR_INVALID_PRIMARY_GROUP: errno.EINVAL,
80 winerror.ERROR_INVALID_PRIMARY_GROUP: errno.EINVAL,
81 winerror.ERROR_INVALID_SIGNAL_NUMBER: errno.EINVAL,
81 winerror.ERROR_INVALID_SIGNAL_NUMBER: errno.EINVAL,
82 winerror.ERROR_INVALID_TARGET_HANDLE: errno.EIO,
82 winerror.ERROR_INVALID_TARGET_HANDLE: errno.EIO,
83 winerror.ERROR_INVALID_WORKSTATION: errno.EACCES,
83 winerror.ERROR_INVALID_WORKSTATION: errno.EACCES,
84 winerror.ERROR_IO_DEVICE: errno.EIO,
84 winerror.ERROR_IO_DEVICE: errno.EIO,
85 winerror.ERROR_IO_INCOMPLETE: errno.EINTR,
85 winerror.ERROR_IO_INCOMPLETE: errno.EINTR,
86 winerror.ERROR_LOCKED: errno.EBUSY,
86 winerror.ERROR_LOCKED: errno.EBUSY,
87 winerror.ERROR_LOCK_VIOLATION: errno.EACCES,
87 winerror.ERROR_LOCK_VIOLATION: errno.EACCES,
88 winerror.ERROR_LOGON_FAILURE: errno.EACCES,
88 winerror.ERROR_LOGON_FAILURE: errno.EACCES,
89 winerror.ERROR_MAPPED_ALIGNMENT: errno.EINVAL,
89 winerror.ERROR_MAPPED_ALIGNMENT: errno.EINVAL,
90 winerror.ERROR_META_EXPANSION_TOO_LONG: errno.E2BIG,
90 winerror.ERROR_META_EXPANSION_TOO_LONG: errno.E2BIG,
91 winerror.ERROR_MORE_DATA: errno.EPIPE,
91 winerror.ERROR_MORE_DATA: errno.EPIPE,
92 winerror.ERROR_NEGATIVE_SEEK: errno.ESPIPE,
92 winerror.ERROR_NEGATIVE_SEEK: errno.ESPIPE,
93 winerror.ERROR_NOACCESS: errno.EFAULT,
93 winerror.ERROR_NOACCESS: errno.EFAULT,
94 winerror.ERROR_NONE_MAPPED: errno.EINVAL,
94 winerror.ERROR_NONE_MAPPED: errno.EINVAL,
95 winerror.ERROR_NOT_ENOUGH_MEMORY: errno.ENOMEM,
95 winerror.ERROR_NOT_ENOUGH_MEMORY: errno.ENOMEM,
96 winerror.ERROR_NOT_READY: errno.EAGAIN,
96 winerror.ERROR_NOT_READY: errno.EAGAIN,
97 winerror.ERROR_NOT_SAME_DEVICE: errno.EXDEV,
97 winerror.ERROR_NOT_SAME_DEVICE: errno.EXDEV,
98 winerror.ERROR_NO_DATA: errno.EPIPE,
98 winerror.ERROR_NO_DATA: errno.EPIPE,
99 winerror.ERROR_NO_MORE_SEARCH_HANDLES: errno.EIO,
99 winerror.ERROR_NO_MORE_SEARCH_HANDLES: errno.EIO,
100 winerror.ERROR_NO_PROC_SLOTS: errno.EAGAIN,
100 winerror.ERROR_NO_PROC_SLOTS: errno.EAGAIN,
101 winerror.ERROR_NO_SUCH_PRIVILEGE: errno.EACCES,
101 winerror.ERROR_NO_SUCH_PRIVILEGE: errno.EACCES,
102 winerror.ERROR_OPEN_FAILED: errno.EIO,
102 winerror.ERROR_OPEN_FAILED: errno.EIO,
103 winerror.ERROR_OPEN_FILES: errno.EBUSY,
103 winerror.ERROR_OPEN_FILES: errno.EBUSY,
104 winerror.ERROR_OPERATION_ABORTED: errno.EINTR,
104 winerror.ERROR_OPERATION_ABORTED: errno.EINTR,
105 winerror.ERROR_OUTOFMEMORY: errno.ENOMEM,
105 winerror.ERROR_OUTOFMEMORY: errno.ENOMEM,
106 winerror.ERROR_PASSWORD_EXPIRED: errno.EACCES,
106 winerror.ERROR_PASSWORD_EXPIRED: errno.EACCES,
107 winerror.ERROR_PATH_BUSY: errno.EBUSY,
107 winerror.ERROR_PATH_BUSY: errno.EBUSY,
108 winerror.ERROR_PATH_NOT_FOUND: errno.ENOENT,
108 winerror.ERROR_PATH_NOT_FOUND: errno.ENOENT,
109 winerror.ERROR_PIPE_BUSY: errno.EBUSY,
109 winerror.ERROR_PIPE_BUSY: errno.EBUSY,
110 winerror.ERROR_PIPE_CONNECTED: errno.EPIPE,
110 winerror.ERROR_PIPE_CONNECTED: errno.EPIPE,
111 winerror.ERROR_PIPE_LISTENING: errno.EPIPE,
111 winerror.ERROR_PIPE_LISTENING: errno.EPIPE,
112 winerror.ERROR_PIPE_NOT_CONNECTED: errno.EPIPE,
112 winerror.ERROR_PIPE_NOT_CONNECTED: errno.EPIPE,
113 winerror.ERROR_PRIVILEGE_NOT_HELD: errno.EACCES,
113 winerror.ERROR_PRIVILEGE_NOT_HELD: errno.EACCES,
114 winerror.ERROR_READ_FAULT: errno.EIO,
114 winerror.ERROR_READ_FAULT: errno.EIO,
115 winerror.ERROR_SEEK: errno.EIO,
115 winerror.ERROR_SEEK: errno.EIO,
116 winerror.ERROR_SEEK_ON_DEVICE: errno.ESPIPE,
116 winerror.ERROR_SEEK_ON_DEVICE: errno.ESPIPE,
117 winerror.ERROR_SHARING_BUFFER_EXCEEDED: errno.ENFILE,
117 winerror.ERROR_SHARING_BUFFER_EXCEEDED: errno.ENFILE,
118 winerror.ERROR_SHARING_VIOLATION: errno.EACCES,
118 winerror.ERROR_SHARING_VIOLATION: errno.EACCES,
119 winerror.ERROR_STACK_OVERFLOW: errno.ENOMEM,
119 winerror.ERROR_STACK_OVERFLOW: errno.ENOMEM,
120 winerror.ERROR_SWAPERROR: errno.ENOENT,
120 winerror.ERROR_SWAPERROR: errno.ENOENT,
121 winerror.ERROR_TOO_MANY_MODULES: errno.EMFILE,
121 winerror.ERROR_TOO_MANY_MODULES: errno.EMFILE,
122 winerror.ERROR_TOO_MANY_OPEN_FILES: errno.EMFILE,
122 winerror.ERROR_TOO_MANY_OPEN_FILES: errno.EMFILE,
123 winerror.ERROR_UNRECOGNIZED_MEDIA: errno.ENXIO,
123 winerror.ERROR_UNRECOGNIZED_MEDIA: errno.ENXIO,
124 winerror.ERROR_UNRECOGNIZED_VOLUME: errno.ENODEV,
124 winerror.ERROR_UNRECOGNIZED_VOLUME: errno.ENODEV,
125 winerror.ERROR_WAIT_NO_CHILDREN: errno.ECHILD,
125 winerror.ERROR_WAIT_NO_CHILDREN: errno.ECHILD,
126 winerror.ERROR_WRITE_FAULT: errno.EIO,
126 winerror.ERROR_WRITE_FAULT: errno.EIO,
127 winerror.ERROR_WRITE_PROTECT: errno.EROFS,
127 winerror.ERROR_WRITE_PROTECT: errno.EROFS,
128 }
128 }
129
129
130 def __init__(self, err):
130 def __init__(self, err):
131 self.win_errno, self.win_function, self.win_strerror = err
131 self.win_errno, self.win_function, self.win_strerror = err
132 if self.win_strerror.endswith('.'):
132 if self.win_strerror.endswith('.'):
133 self.win_strerror = self.win_strerror[:-1]
133 self.win_strerror = self.win_strerror[:-1]
134
134
135 class WinIOError(WinError, IOError):
135 class WinIOError(WinError, IOError):
136 def __init__(self, err, filename=None):
136 def __init__(self, err, filename=None):
137 WinError.__init__(self, err)
137 WinError.__init__(self, err)
138 IOError.__init__(self, self.winerror_map.get(self.win_errno, 0),
138 IOError.__init__(self, self.winerror_map.get(self.win_errno, 0),
139 self.win_strerror)
139 self.win_strerror)
140 self.filename = filename
140 self.filename = filename
141
141
142 class WinOSError(WinError, OSError):
142 class WinOSError(WinError, OSError):
143 def __init__(self, err):
143 def __init__(self, err):
144 WinError.__init__(self, err)
144 WinError.__init__(self, err)
145 OSError.__init__(self, self.winerror_map.get(self.win_errno, 0),
145 OSError.__init__(self, self.winerror_map.get(self.win_errno, 0),
146 self.win_strerror)
146 self.win_strerror)
147
147
148 def os_link(src, dst):
148 def os_link(src, dst):
149 try:
149 try:
150 win32file.CreateHardLink(dst, src)
150 win32file.CreateHardLink(dst, src)
151 # CreateHardLink sometimes succeeds on mapped drives but
151 # CreateHardLink sometimes succeeds on mapped drives but
152 # following nlinks() returns 1. Check it now and bail out.
152 # following nlinks() returns 1. Check it now and bail out.
153 if nlinks(src) < 2:
153 if nlinks(src) < 2:
154 try:
154 try:
155 win32file.DeleteFile(dst)
155 win32file.DeleteFile(dst)
156 except:
156 except:
157 pass
157 pass
158 # Fake hardlinking error
158 # Fake hardlinking error
159 raise WinOSError((18, 'CreateHardLink', 'The system cannot '
159 raise WinOSError((18, 'CreateHardLink', 'The system cannot '
160 'move the file to a different disk drive'))
160 'move the file to a different disk drive'))
161 except pywintypes.error, details:
161 except pywintypes.error, details:
162 raise WinOSError(details)
162 raise WinOSError(details)
163
163
164 def nlinks(pathname):
164 def nlinks(pathname):
165 """Return number of hardlinks for the given file."""
165 """Return number of hardlinks for the given file."""
166 try:
166 try:
167 fh = win32file.CreateFile(pathname,
167 fh = win32file.CreateFile(pathname,
168 win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
168 win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
169 None, win32file.OPEN_EXISTING, 0, None)
169 None, win32file.OPEN_EXISTING, 0, None)
170 res = win32file.GetFileInformationByHandle(fh)
170 res = win32file.GetFileInformationByHandle(fh)
171 fh.Close()
171 fh.Close()
172 return res[7]
172 return res[7]
173 except pywintypes.error:
173 except pywintypes.error:
174 return os.lstat(pathname).st_nlink
174 return os.lstat(pathname).st_nlink
175
175
176 def testpid(pid):
176 def testpid(pid):
177 '''return True if pid is still running or unable to
177 '''return True if pid is still running or unable to
178 determine, False otherwise'''
178 determine, False otherwise'''
179 try:
179 try:
180 handle = win32api.OpenProcess(
180 handle = win32api.OpenProcess(
181 win32con.PROCESS_QUERY_INFORMATION, False, pid)
181 win32con.PROCESS_QUERY_INFORMATION, False, pid)
182 if handle:
182 if handle:
183 status = win32process.GetExitCodeProcess(handle)
183 status = win32process.GetExitCodeProcess(handle)
184 return status == win32con.STILL_ACTIVE
184 return status == win32con.STILL_ACTIVE
185 except pywintypes.error, details:
185 except pywintypes.error, details:
186 return details[0] != winerror.ERROR_INVALID_PARAMETER
186 return details[0] != winerror.ERROR_INVALID_PARAMETER
187 return True
187 return True
188
188
189 def lookup_reg(key, valname=None, scope=None):
189 def lookup_reg(key, valname=None, scope=None):
190 ''' Look up a key/value name in the Windows registry.
190 ''' Look up a key/value name in the Windows registry.
191
191
192 valname: value name. If unspecified, the default value for the key
192 valname: value name. If unspecified, the default value for the key
193 is used.
193 is used.
194 scope: optionally specify scope for registry lookup, this can be
194 scope: optionally specify scope for registry lookup, this can be
195 a sequence of scopes to look up in order. Default (CURRENT_USER,
195 a sequence of scopes to look up in order. Default (CURRENT_USER,
196 LOCAL_MACHINE).
196 LOCAL_MACHINE).
197 '''
197 '''
198 try:
198 try:
199 from _winreg import HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, \
199 from _winreg import HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, \
200 QueryValueEx, OpenKey
200 QueryValueEx, OpenKey
201 except ImportError:
201 except ImportError:
202 return None
202 return None
203
203
204 def query_val(scope, key, valname):
205 try:
206 keyhandle = OpenKey(scope, key)
207 return QueryValueEx(keyhandle, valname)[0]
208 except EnvironmentError:
209 return None
210
211 if scope is None:
204 if scope is None:
212 scope = (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE)
205 scope = (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE)
213 elif not isinstance(scope, (list, tuple)):
206 elif not isinstance(scope, (list, tuple)):
214 scope = (scope,)
207 scope = (scope,)
215 for s in scope:
208 for s in scope:
216 val = query_val(s, key, valname)
209 try:
217 if val is not None:
210 val = QueryValueEx(OpenKey(scope, key), valname)[0]
218 return val
211 # never let a Unicode string escape into the wild
212 return util.tolocal(val.encode('UTF-8'))
213 except EnvironmentError:
214 pass
219
215
220 def system_rcpath_win32():
216 def system_rcpath_win32():
221 '''return default os-specific hgrc search path'''
217 '''return default os-specific hgrc search path'''
222 proc = win32api.GetCurrentProcess()
218 proc = win32api.GetCurrentProcess()
223 try:
219 try:
224 # This will fail on windows < NT
220 # This will fail on windows < NT
225 filename = win32process.GetModuleFileNameEx(proc, 0)
221 filename = win32process.GetModuleFileNameEx(proc, 0)
226 except:
222 except:
227 filename = win32api.GetModuleFileName(0)
223 filename = win32api.GetModuleFileName(0)
228 # Use mercurial.ini found in directory with hg.exe
224 # Use mercurial.ini found in directory with hg.exe
229 progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
225 progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
230 if os.path.isfile(progrc):
226 if os.path.isfile(progrc):
231 return [progrc]
227 return [progrc]
232 # else look for a system rcpath in the registry
228 # else look for a system rcpath in the registry
233 try:
229 try:
234 value = win32api.RegQueryValue(
230 value = win32api.RegQueryValue(
235 win32con.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Mercurial')
231 win32con.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Mercurial')
236 rcpath = []
232 rcpath = []
237 for p in value.split(os.pathsep):
233 for p in value.split(os.pathsep):
238 if p.lower().endswith('mercurial.ini'):
234 if p.lower().endswith('mercurial.ini'):
239 rcpath.append(p)
235 rcpath.append(p)
240 elif os.path.isdir(p):
236 elif os.path.isdir(p):
241 for f, kind in osutil.listdir(p):
237 for f, kind in osutil.listdir(p):
242 if f.endswith('.rc'):
238 if f.endswith('.rc'):
243 rcpath.append(os.path.join(p, f))
239 rcpath.append(os.path.join(p, f))
244 return rcpath
240 return rcpath
245 except pywintypes.error:
241 except pywintypes.error:
246 return []
242 return []
247
243
248 def user_rcpath_win32():
244 def user_rcpath_win32():
249 '''return os-specific hgrc search path to the user dir'''
245 '''return os-specific hgrc search path to the user dir'''
250 userdir = os.path.expanduser('~')
246 userdir = os.path.expanduser('~')
251 if sys.getwindowsversion() != 2 and userdir == '~':
247 if sys.getwindowsversion() != 2 and userdir == '~':
252 # We are on win < nt: fetch the APPDATA directory location and use
248 # We are on win < nt: fetch the APPDATA directory location and use
253 # the parent directory as the user home dir.
249 # the parent directory as the user home dir.
254 appdir = shell.SHGetPathFromIDList(
250 appdir = shell.SHGetPathFromIDList(
255 shell.SHGetSpecialFolderLocation(0, shellcon.CSIDL_APPDATA))
251 shell.SHGetSpecialFolderLocation(0, shellcon.CSIDL_APPDATA))
256 userdir = os.path.dirname(appdir)
252 userdir = os.path.dirname(appdir)
257 return [os.path.join(userdir, 'mercurial.ini'),
253 return [os.path.join(userdir, 'mercurial.ini'),
258 os.path.join(userdir, '.hgrc')]
254 os.path.join(userdir, '.hgrc')]
259
255
260 class posixfile_nt(object):
256 class posixfile_nt(object):
261 '''file object with posix-like semantics. on windows, normal
257 '''file object with posix-like semantics. on windows, normal
262 files can not be deleted or renamed if they are open. must open
258 files can not be deleted or renamed if they are open. must open
263 with win32file.FILE_SHARE_DELETE. this flag does not exist on
259 with win32file.FILE_SHARE_DELETE. this flag does not exist on
264 windows < nt, so do not use this class there.'''
260 windows < nt, so do not use this class there.'''
265
261
266 # tried to use win32file._open_osfhandle to pass fd to os.fdopen,
262 # tried to use win32file._open_osfhandle to pass fd to os.fdopen,
267 # but does not work at all. wrap win32 file api instead.
263 # but does not work at all. wrap win32 file api instead.
268
264
269 def __init__(self, name, mode='rb'):
265 def __init__(self, name, mode='rb'):
270 self.closed = False
266 self.closed = False
271 self.name = name
267 self.name = name
272 self.mode = mode
268 self.mode = mode
273 access = 0
269 access = 0
274 if 'r' in mode or '+' in mode:
270 if 'r' in mode or '+' in mode:
275 access |= win32file.GENERIC_READ
271 access |= win32file.GENERIC_READ
276 if 'w' in mode or 'a' in mode or '+' in mode:
272 if 'w' in mode or 'a' in mode or '+' in mode:
277 access |= win32file.GENERIC_WRITE
273 access |= win32file.GENERIC_WRITE
278 if 'r' in mode:
274 if 'r' in mode:
279 creation = win32file.OPEN_EXISTING
275 creation = win32file.OPEN_EXISTING
280 elif 'a' in mode:
276 elif 'a' in mode:
281 creation = win32file.OPEN_ALWAYS
277 creation = win32file.OPEN_ALWAYS
282 else:
278 else:
283 creation = win32file.CREATE_ALWAYS
279 creation = win32file.CREATE_ALWAYS
284 try:
280 try:
285 self.handle = win32file.CreateFile(name,
281 self.handle = win32file.CreateFile(name,
286 access,
282 access,
287 win32file.FILE_SHARE_READ |
283 win32file.FILE_SHARE_READ |
288 win32file.FILE_SHARE_WRITE |
284 win32file.FILE_SHARE_WRITE |
289 win32file.FILE_SHARE_DELETE,
285 win32file.FILE_SHARE_DELETE,
290 None,
286 None,
291 creation,
287 creation,
292 win32file.FILE_ATTRIBUTE_NORMAL,
288 win32file.FILE_ATTRIBUTE_NORMAL,
293 0)
289 0)
294 except pywintypes.error, err:
290 except pywintypes.error, err:
295 raise WinIOError(err, name)
291 raise WinIOError(err, name)
296
292
297 def __iter__(self):
293 def __iter__(self):
298 for line in self.read().splitlines(True):
294 for line in self.read().splitlines(True):
299 yield line
295 yield line
300
296
301 def read(self, count=-1):
297 def read(self, count=-1):
302 try:
298 try:
303 cs = cStringIO.StringIO()
299 cs = cStringIO.StringIO()
304 while count:
300 while count:
305 wincount = int(count)
301 wincount = int(count)
306 if wincount == -1:
302 if wincount == -1:
307 wincount = 1048576
303 wincount = 1048576
308 val, data = win32file.ReadFile(self.handle, wincount)
304 val, data = win32file.ReadFile(self.handle, wincount)
309 if not data: break
305 if not data: break
310 cs.write(data)
306 cs.write(data)
311 if count != -1:
307 if count != -1:
312 count -= len(data)
308 count -= len(data)
313 return cs.getvalue()
309 return cs.getvalue()
314 except pywintypes.error, err:
310 except pywintypes.error, err:
315 raise WinIOError(err)
311 raise WinIOError(err)
316
312
317 def write(self, data):
313 def write(self, data):
318 try:
314 try:
319 if 'a' in self.mode:
315 if 'a' in self.mode:
320 win32file.SetFilePointer(self.handle, 0, win32file.FILE_END)
316 win32file.SetFilePointer(self.handle, 0, win32file.FILE_END)
321 nwrit = 0
317 nwrit = 0
322 while nwrit < len(data):
318 while nwrit < len(data):
323 val, nwrit = win32file.WriteFile(self.handle, data)
319 val, nwrit = win32file.WriteFile(self.handle, data)
324 data = data[nwrit:]
320 data = data[nwrit:]
325 except pywintypes.error, err:
321 except pywintypes.error, err:
326 raise WinIOError(err)
322 raise WinIOError(err)
327
323
328 def writelines(self, sequence):
324 def writelines(self, sequence):
329 for s in sequence:
325 for s in sequence:
330 self.write(s)
326 self.write(s)
331
327
332 def seek(self, pos, whence=0):
328 def seek(self, pos, whence=0):
333 try:
329 try:
334 win32file.SetFilePointer(self.handle, int(pos), whence)
330 win32file.SetFilePointer(self.handle, int(pos), whence)
335 except pywintypes.error, err:
331 except pywintypes.error, err:
336 raise WinIOError(err)
332 raise WinIOError(err)
337
333
338 def tell(self):
334 def tell(self):
339 try:
335 try:
340 return win32file.SetFilePointer(self.handle, 0,
336 return win32file.SetFilePointer(self.handle, 0,
341 win32file.FILE_CURRENT)
337 win32file.FILE_CURRENT)
342 except pywintypes.error, err:
338 except pywintypes.error, err:
343 raise WinIOError(err)
339 raise WinIOError(err)
344
340
345 def close(self):
341 def close(self):
346 if not self.closed:
342 if not self.closed:
347 self.handle = None
343 self.handle = None
348 self.closed = True
344 self.closed = True
349
345
350 def flush(self):
346 def flush(self):
351 # we have no application-level buffering
347 # we have no application-level buffering
352 pass
348 pass
353
349
354 def truncate(self, pos=0):
350 def truncate(self, pos=0):
355 try:
351 try:
356 win32file.SetFilePointer(self.handle, int(pos),
352 win32file.SetFilePointer(self.handle, int(pos),
357 win32file.FILE_BEGIN)
353 win32file.FILE_BEGIN)
358 win32file.SetEndOfFile(self.handle)
354 win32file.SetEndOfFile(self.handle)
359 except pywintypes.error, err:
355 except pywintypes.error, err:
360 raise WinIOError(err)
356 raise WinIOError(err)
361
357
362 getuser_fallback = win32api.GetUserName
358 getuser_fallback = win32api.GetUserName
363
359
364 def set_signal_handler_win32():
360 def set_signal_handler_win32():
365 """Register a termination handler for console events including
361 """Register a termination handler for console events including
366 CTRL+C. python signal handlers do not work well with socket
362 CTRL+C. python signal handlers do not work well with socket
367 operations.
363 operations.
368 """
364 """
369 def handler(event):
365 def handler(event):
370 win32process.ExitProcess(1)
366 win32process.ExitProcess(1)
371 win32api.SetConsoleCtrlHandler(handler)
367 win32api.SetConsoleCtrlHandler(handler)
General Comments 0
You need to be logged in to leave comments. Login now