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