diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2015-11-05 18:34:34 +0100 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2015-11-05 18:34:34 +0100 |
commit | c56dc181f907f8ab6dbcd40b9baf66f80d88468a (patch) | |
tree | 4c0de52dc2c12ead38f764adae31b4b16d33e108 /winsup/cygwin/mount.cc | |
parent | 41299df081a0a7edc646caf84d208145624a1d37 (diff) | |
download | newlib-c56dc181f907f8ab6dbcd40b9baf66f80d88468a.zip newlib-c56dc181f907f8ab6dbcd40b9baf66f80d88468a.tar.gz newlib-c56dc181f907f8ab6dbcd40b9baf66f80d88468a.tar.bz2 |
Fake volume serial number on filesystems not providing it
* mount.cc (fs_info::update): Fake a serial number on filesystems not
providing one.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup/cygwin/mount.cc')
-rw-r--r-- | winsup/cygwin/mount.cc | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index 66e8571..c04805b 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -182,8 +182,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) clear (); /* Always caseinsensitive. We really just need access to the drive. */ - InitializeObjectAttributes (&attr, upath, OBJ_CASE_INSENSITIVE, NULL, - NULL); + InitializeObjectAttributes (&attr, upath, OBJ_CASE_INSENSITIVE, NULL, NULL); if (in_vol) vol = in_vol; else @@ -232,6 +231,33 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) uint32_t hash = 0; if (NT_SUCCESS (status)) { + /* If the FS doesn't return a valid serial number (PrlSF is a candidate), + create reproducible serial number from path. We need this to create + a unique per-drive/share hash. */ + if (ffvi_buf.ffvi.VolumeSerialNumber == 0) + { + UNICODE_STRING path_prefix; + WCHAR *p; + + if (upath->Buffer[5] == L':' && upath->Buffer[6] == L'\\') + p = upath->Buffer + 6; + else + { + /* We're expecting an UNC path. Move p to the backslash after + "\??\UNC\server\share" or the trailing NUL. */ + p = upath->Buffer + 7; /* Skip "\??\UNC" */ + int bs_cnt = 0; + + while (*++p) + if (*p == L'\\') + if (++bs_cnt > 1) + break; + } + RtlInitCountedUnicodeString (&path_prefix, upath->Buffer, + (p - upath->Buffer) * sizeof (WCHAR)); + ffvi_buf.ffvi.VolumeSerialNumber = hash_path_name ((ino_t) 0, + &path_prefix); + } fs_info *fsi = fsi_cache.search (&ffvi_buf.ffvi, hash); if (fsi) { |