2009-08-24 Corinna Vinschen <corinna@vinschen.de>
+ * mount.cc (fs_info::update): Add comment.
+ * path.cc (symlink_info::check_reparse_point): Return -1 for volume
+ mount points. Explain why.
+ (symlink_info::check): Call fs.update again for volume mount points.
+ Explain why.
+
+2009-08-24 Corinna Vinschen <corinna@vinschen.de>
+
* globals.cc (ro_u_volume): New R/O unicode string.
* path.cc (symlink_info::check_reparse_point): Fix check for volume
mount points to work on Vista and later as well.
/* Always caseinsensitive. We really just need access to the drive. */
InitializeObjectAttributes (&attr, upath, OBJ_CASE_INSENSITIVE, NULL,
NULL);
+ /* Note: Don't use the FILE_OPEN_REPARSE_POINT flag here. The reason
+ is that symlink_info::check relies on being able to open a handle
+ to the target of a volume mount point. */
status = NtOpenFile (&vol, access, &attr, &io, FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT);
/* At least one filesystem (HGFS, VMware shared folders) doesn't like
if (rp->MountPointReparseBuffer.PrintNameLength == 0
|| RtlEqualUnicodePathPrefix (&subst, &ro_u_volume, TRUE))
{
- /* Volume mount point. Not treated as symlink. */
- return 0;
+ /* Volume mount point. Not treated as symlink. The return
+ value of -1 is a hint for the caller to treat this as a
+ volume mount point. */
+ return -1;
}
sys_wcstombs (srcbuf, SYMLINK_MAX + 1,
(WCHAR *)((char *)rp->MountPointReparseBuffer.PathBuffer
else if (fileattr & FILE_ATTRIBUTE_REPARSE_POINT)
{
res = check_reparse_point (h);
- if (res)
+ if (res == -1)
+ {
+ /* Volume mount point. The filesystem information for the top
+ level directory should be for the volume top level directory
+ itself, rather than for the reparse point itself. So we
+ fetch the filesystem information again, but with a NULL
+ handle. This does what we want because fs_info::update opens
+ the handle without FILE_OPEN_REPARSE_POINT. */
+ fs.update (&upath, NULL);
+ }
+ else if (res)
break;
}