From 4794666df619fbfd7d36620163b51bda31322773 Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Wed, 13 May 2015 14:42:31 +0100 Subject: [PATCH] On Windows, the user's home directory may be either %USERPROFILE% or %HOMEDRIVE%%HOMEPATH% depending on the Windows version. fixes ticket:2417 Signed-off-by: Daira Hopwood --- src/allmydata/test/test_util.py | 13 ++++++++++--- src/allmydata/util/fileutil.py | 24 +++++++++++++++++++----- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/allmydata/test/test_util.py b/src/allmydata/test/test_util.py index f2da9c4b..a2bba112 100644 --- a/src/allmydata/test/test_util.py +++ b/src/allmydata/test/test_util.py @@ -539,10 +539,11 @@ class FileUtil(ReallyEqualMixin, unittest.TestCase): _cleanup() self.failIf(os.path.exists(long_path)) - def test_windows_expanduser(self): + def _test_windows_expanduser(self, userprofile=None, homedrive=None, homepath=None): def call_windows_getenv(name): - if name == u"HOMEDRIVE": return u"C:" - if name == u"HOMEPATH": return u"\\Documents and Settings\\\u0100" + if name == u"USERPROFILE": return userprofile + if name == u"HOMEDRIVE": return homedrive + if name == u"HOMEPATH": return homepath self.fail("unexpected argument to call_windows_getenv") self.patch(fileutil, 'windows_getenv', call_windows_getenv) @@ -553,6 +554,12 @@ class FileUtil(ReallyEqualMixin, unittest.TestCase): self.failUnlessReallyEqual(fileutil.windows_expanduser(u"a~"), u"a~") self.failUnlessReallyEqual(fileutil.windows_expanduser(u"a\\~\\foo"), u"a\\~\\foo") + def test_windows_expanduser_xp(self): + return self._test_windows_expanduser(homedrive=u"C:", homepath=u"\\Documents and Settings\\\u0100") + + def test_windows_expanduser_win7(self): + return self._test_windows_expanduser(userprofile=os.path.join(u"C:", u"\\Documents and Settings\\\u0100")) + def test_disk_stats(self): avail = fileutil.get_available_space('.', 2**14) if avail == 0: diff --git a/src/allmydata/util/fileutil.py b/src/allmydata/util/fileutil.py index 4dd501ce..0349669e 100644 --- a/src/allmydata/util/fileutil.py +++ b/src/allmydata/util/fileutil.py @@ -396,18 +396,28 @@ def expanduser(path): def windows_expanduser(path): if not path.startswith('~'): return path - home_drive = windows_getenv(u'HOMEDRIVE') - home_path = windows_getenv(u'HOMEPATH') + + home_dir = windows_getenv(u'USERPROFILE') + if home_dir is None: + home_drive = windows_getenv(u'HOMEDRIVE') + home_path = windows_getenv(u'HOMEPATH') + if home_drive is None or home_path is None: + raise OSError("Could not find home directory: neither %USERPROFILE% nor (%HOMEDRIVE% and %HOMEPATH%) are set.") + home_dir = os.path.join(home_drive, home_path) + if path == '~': - return os.path.join(home_drive, home_path) + return home_dir elif path.startswith('~/') or path.startswith('~\\'): - return os.path.join(home_drive, home_path, path[2 :]) + return os.path.join(home_dir, path[2 :]) else: return path +# +ERROR_ENVVAR_NOT_FOUND = 203 + def windows_getenv(name): # Based on , - # with improved error handling. + # with improved error handling. Returns None if there is no enivronment variable of the given name. if not isinstance(name, unicode): raise AssertionError("name must be Unicode") @@ -415,6 +425,8 @@ def windows_getenv(name): # GetEnvironmentVariableW returns DWORD, so n cannot be negative. if n == 0: err = GetLastError() + if err == ERROR_ENVVAR_NOT_FOUND: + return None raise OSError("Windows error %d attempting to read size of environment variable %r" % (err, name)) if n == 1: @@ -426,6 +438,8 @@ def windows_getenv(name): retval = GetEnvironmentVariableW(name, buf, n) if retval == 0: err = GetLastError() + if err == ERROR_ENVVAR_NOT_FOUND: + return None raise OSError("Windows error %d attempting to read environment variable %r" % (err, name)) if retval >= n: -- 2.37.2