* 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.
This commit is contained in:
Corinna Vinschen 2009-08-25 11:27:03 +00:00
parent 162a23c504
commit c177980e75
3 changed files with 26 additions and 3 deletions

View File

@ -1,3 +1,11 @@
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> 2009-08-24 Corinna Vinschen <corinna@vinschen.de>
* globals.cc (ro_u_volume): New R/O unicode string. * globals.cc (ro_u_volume): New R/O unicode string.

View File

@ -134,6 +134,9 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
/* Always caseinsensitive. We really just need access to the drive. */ /* Always caseinsensitive. We really just need access to the drive. */
InitializeObjectAttributes (&attr, upath, OBJ_CASE_INSENSITIVE, NULL, InitializeObjectAttributes (&attr, upath, OBJ_CASE_INSENSITIVE, NULL,
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, status = NtOpenFile (&vol, access, &attr, &io, FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT); FILE_OPEN_FOR_BACKUP_INTENT);
/* At least one filesystem (HGFS, VMware shared folders) doesn't like /* At least one filesystem (HGFS, VMware shared folders) doesn't like

View File

@ -1874,8 +1874,10 @@ symlink_info::check_reparse_point (HANDLE h)
if (rp->MountPointReparseBuffer.PrintNameLength == 0 if (rp->MountPointReparseBuffer.PrintNameLength == 0
|| RtlEqualUnicodePathPrefix (&subst, &ro_u_volume, TRUE)) || RtlEqualUnicodePathPrefix (&subst, &ro_u_volume, TRUE))
{ {
/* Volume mount point. Not treated as symlink. */ /* Volume mount point. Not treated as symlink. The return
return 0; 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, sys_wcstombs (srcbuf, SYMLINK_MAX + 1,
(WCHAR *)((char *)rp->MountPointReparseBuffer.PathBuffer (WCHAR *)((char *)rp->MountPointReparseBuffer.PathBuffer
@ -2410,7 +2412,17 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
else if (fileattr & FILE_ATTRIBUTE_REPARSE_POINT) else if (fileattr & FILE_ATTRIBUTE_REPARSE_POINT)
{ {
res = check_reparse_point (h); 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; break;
} }