mirror of
https://git.code.sf.net/p/ntfs-3g/ntfs-3g.git
synced 2024-12-03 23:13:39 +08:00
Processed junctions and symlinks whose target references another one
When the target of a junction or a Windows-type symlink references another junction or symlink, the search for the full path on the current partition and its translation for case-sensitive access is interrupted. The target can now be dereferenced, provided the end of the path needed no translation.
This commit is contained in:
parent
ab6f7c027d
commit
db5af00af6
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This module is part of ntfs-3g library
|
||||
*
|
||||
* Copyright (c) 2008-2009 Jean-Pierre Andre
|
||||
* Copyright (c) 2008-2012 Jean-Pierre Andre
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as published
|
||||
@ -236,6 +236,17 @@ static char *search_absolute(ntfs_volume *vol, ntfschar *path,
|
||||
ni = ntfs_inode_open(vol, (MFT_REF)FILE_root);
|
||||
if (ni) {
|
||||
start = 0;
|
||||
/*
|
||||
* Examine and translate the path, until we reach either
|
||||
* - the end,
|
||||
* - an unknown item
|
||||
* - a non-directory
|
||||
* - another reparse point,
|
||||
* A reparse point is not dereferenced, it will be
|
||||
* examined later when the translated path is dereferenced,
|
||||
* however the final part of the path will not be adjusted
|
||||
* to correct case.
|
||||
*/
|
||||
do {
|
||||
len = 0;
|
||||
while (((start + len) < count)
|
||||
@ -253,9 +264,11 @@ static char *search_absolute(ntfs_volume *vol, ntfschar *path,
|
||||
}
|
||||
} while (ni
|
||||
&& (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
|
||||
&& !(ni->flags & FILE_ATTR_REPARSE_POINT)
|
||||
&& (start < count));
|
||||
if (ni
|
||||
&& (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY ? isdir : !isdir))
|
||||
&& ((ni->mrec->flags & MFT_RECORD_IS_DIRECTORY ? isdir : !isdir)
|
||||
|| (ni->flags & FILE_ATTR_REPARSE_POINT)))
|
||||
if (ntfs_ucstombs(path, count, &target, 0) < 0) {
|
||||
if (target) {
|
||||
free(target);
|
||||
@ -289,12 +302,25 @@ static char *search_relative(ntfs_inode *ni, ntfschar *path, int count)
|
||||
int pos;
|
||||
int lth;
|
||||
BOOL ok;
|
||||
BOOL morelinks;
|
||||
int max = 32; /* safety */
|
||||
|
||||
pos = 0;
|
||||
ok = TRUE;
|
||||
morelinks = FALSE;
|
||||
curni = ntfs_dir_parent_inode(ni);
|
||||
while (curni && ok && (pos < (count - 1)) && --max) {
|
||||
/*
|
||||
* Examine and translate the path, until we reach either
|
||||
* - the end,
|
||||
* - an unknown item
|
||||
* - a non-directory
|
||||
* - another reparse point,
|
||||
* A reparse point is not dereferenced, it will be
|
||||
* examined later when the translated path is dereferenced,
|
||||
* however the final part of the path will not be adjusted
|
||||
* to correct case.
|
||||
*/
|
||||
while (curni && ok && !morelinks && (pos < (count - 1)) && --max) {
|
||||
if ((count >= (pos + 2))
|
||||
&& (path[pos] == const_cpu_to_le16('.'))
|
||||
&& (path[pos+1] == const_cpu_to_le16('\\'))) {
|
||||
@ -332,12 +358,18 @@ static char *search_relative(ntfs_inode *ni, ntfschar *path, int count)
|
||||
if (!curni)
|
||||
ok = FALSE;
|
||||
else {
|
||||
if (curni->flags & FILE_ATTR_REPARSE_POINT)
|
||||
morelinks = TRUE;
|
||||
if (ok && ((pos + lth) < count)) {
|
||||
path[pos + lth] = const_cpu_to_le16('/');
|
||||
pos += lth + 1;
|
||||
if (morelinks
|
||||
&& ntfs_inode_close(curni))
|
||||
ok = FALSE;
|
||||
} else {
|
||||
pos += lth;
|
||||
if ((ni->mrec->flags ^ curni->mrec->flags)
|
||||
if (!morelinks
|
||||
&& (ni->mrec->flags ^ curni->mrec->flags)
|
||||
& MFT_RECORD_IS_DIRECTORY)
|
||||
ok = FALSE;
|
||||
if (ntfs_inode_close(curni))
|
||||
|
Loading…
Reference in New Issue
Block a user