# there is always at least one Unicode path component.
return os.path.normpath(path)
-windows = False
-try:
- import win32api, win32con
-except ImportError:
- pass
-else:
- windows = True
- # <http://msdn.microsoft.com/en-us/library/ms680621%28VS.85%29.aspx>
- win32api.SetErrorMode(win32con.SEM_FAILCRITICALERRORS |
- win32con.SEM_NOOPENFILEERRORBOX)
+
+have_GetDiskFreeSpaceExW = False
+if sys.platform == "win32":
+ try:
+ from ctypes import WINFUNCTYPE, windll, POINTER, byref, c_ulonglong
+ from ctypes.wintypes import BOOL, DWORD, LPCWSTR
+
+ # <http://msdn.microsoft.com/en-us/library/aa383742%28v=VS.85%29.aspx>
+ PULARGE_INTEGER = POINTER(c_ulonglong)
+
+ # <http://msdn.microsoft.com/en-us/library/aa364937%28VS.85%29.aspx>
+ GetDiskFreeSpaceExW = WINFUNCTYPE(BOOL, LPCWSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER)(
+ ("GetDiskFreeSpaceExW", windll.kernel32))
+
+ # <http://msdn.microsoft.com/en-us/library/ms679360%28v=VS.85%29.aspx>
+ GetLastError = WINFUNCTYPE(DWORD)(("GetLastError", windll.kernel32))
+
+ have_GetDiskFreeSpaceExW = True
+ except Exception:
+ import traceback
+ traceback.print_exc()
def get_disk_stats(whichdir, reserved_space=0):
"""Return disk statistics for the storage disk, in the form of a dict
filesystem as reserved_space.
"""
- if windows:
- # For Windows systems, where os.statvfs is not available, use GetDiskFreeSpaceEx.
- # <http://docs.activestate.com/activepython/2.5/pywin32/win32api__GetDiskFreeSpaceEx_meth.html>
- #
- # Although the docs say that the argument should be the root directory
- # of a disk, GetDiskFreeSpaceEx actually accepts any path on that disk
- # (like its Win32 equivalent).
-
- (free_for_nonroot, total, free_for_root) = win32api.GetDiskFreeSpaceEx(whichdir)
+ if have_GetDiskFreeSpaceExW:
+ # If this is a Windows system and GetDiskFreeSpaceExW is available, use it.
+ # (This might put up an error dialog unless
+ # SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX) has been called,
+ # which we do in allmydata.windows.fixups.initialize().)
+
+ n_free_for_nonroot = c_ulonglong(0)
+ n_total = c_ulonglong(0)
+ n_free_for_root = c_ulonglong(0)
+ retval = GetDiskFreeSpaceExW(whichdir, byref(n_free_for_nonroot),
+ byref(n_total),
+ byref(n_free_for_root))
+ if retval == 0:
+ raise OSError("Windows error %d attempting to get disk statistics for %r"
+ % (GetLastError(), whichdir))
+ free_for_nonroot = n_free_for_nonroot.value
+ total = n_total.value
+ free_for_root = n_free_for_root.value
else:
# For Unix-like systems.
# <http://docs.python.org/library/os.html#os.statvfs>
used = total - free_for_root
avail = max(free_for_nonroot - reserved_space, 0)
- return { 'total': total, 'free_for_root': free_for_root,
+ return { 'total': total,
+ 'free_for_root': free_for_root,
'free_for_nonroot': free_for_nonroot,
- 'used': used, 'avail': avail, }
+ 'used': used,
+ 'avail': avail,
+ }
def get_available_space(whichdir, reserved_space):
"""Returns available space for share storage in bytes, or None if no
return True
done = True
+ import codecs, re
+ from ctypes import WINFUNCTYPE, windll, POINTER, byref, c_int
+ from ctypes.wintypes import BOOL, HANDLE, DWORD, UINT, LPWSTR, LPCWSTR, LPVOID
+ from allmydata.util import log
+ from allmydata.util.encodingutil import canonical_encoding
+
+ # <http://msdn.microsoft.com/en-us/library/ms680621%28VS.85%29.aspx>
+ SetErrorMode = WINFUNCTYPE(UINT, UINT)(("SetErrorMode", windll.kernel32))
+ SEM_FAILCRITICALERRORS = 0x0001
+ SEM_NOOPENFILEERRORBOX = 0x8000
+
+ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX)
+
original_stderr = sys.stderr
# If any exception occurs in this code, we'll probably try to print it on stderr,
print >>original_stderr, isinstance(message, str) and message or repr(message)
log.msg(message, level=log.WEIRD)
- import codecs, re
- from ctypes import WINFUNCTYPE, windll, POINTER, byref, c_int
- from ctypes.wintypes import BOOL, HANDLE, DWORD, LPWSTR, LPCWSTR, LPVOID
- from allmydata.util import log
- from allmydata.util.encodingutil import canonical_encoding
-
# Work around <http://bugs.python.org/issue6058>.
codecs.register(lambda name: name == 'cp65001' and codecs.lookup('utf-8') or None)