Пример #1
0
static char *search_relative(ntfs_inode *ni, ntfschar *path, int count)
{
	char *target = (char*)NULL;
	ntfs_inode *curni;
	ntfs_inode *newni;
	u64 inum;
	int pos;
	int lth;
	BOOL ok;
	BOOL morelinks;
	int max = 32; /* safety */

	pos = 0;
	ok = TRUE;
	morelinks = FALSE;
	curni = ntfs_dir_parent_inode(ni);
		/*
		 * 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('\\'))) {
			path[1] = const_cpu_to_le16('/');
			pos += 2;
		} else {
			if ((count >= (pos + 3))
			    && (path[pos] == const_cpu_to_le16('.'))
			    &&(path[pos+1] == const_cpu_to_le16('.'))
			    && (path[pos+2] == const_cpu_to_le16('\\'))) {
				path[2] = const_cpu_to_le16('/');
				pos += 3;
				newni = ntfs_dir_parent_inode(curni);
				if (curni != ni)
					ntfs_inode_close(curni);
				curni = newni;
				if (!curni)
					ok = FALSE;
			} else {
				lth = 0;
				while (((pos + lth) < count)
				    && (path[pos + lth] != const_cpu_to_le16('\\')))
					lth++;
				if (lth > 0)
					inum = ntfs_fix_file_name(curni,&path[pos],lth);
				else
					inum = (u64)-1;
				if (!lth
				    || ((curni != ni)
					&& ntfs_inode_close(curni))
				    || (inum == (u64)-1))
					ok = FALSE;
				else {
					curni = ntfs_inode_open(ni->vol, MREF(inum));
					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 (!morelinks
							  && (ni->mrec->flags ^ curni->mrec->flags)
							    & MFT_RECORD_IS_DIRECTORY)
								ok = FALSE;
							if (ntfs_inode_close(curni))
								ok = FALSE;
						}
					}
				}
			}
		}
	}

	if (ok && (ntfs_ucstombs(path, count, &target, 0) < 0)) {
		free(target); // needed ?
		target = (char*)NULL;
	}
	return (target);
}
Пример #2
0
static char *search_relative(ntfs_inode *ni, ntfschar *path, int count)
{
	char *target = (char*)NULL;
	ntfs_inode *curni;
	ntfs_inode *newni;
	u64 inum;
	int pos;
	int lth;
	BOOL ok;
	int max = 32; /* safety */

	pos = 0;
	ok = TRUE;
	curni = ntfs_dir_parent_inode(ni);
	while (curni && ok && (pos < (count - 1)) && --max) {
		if ((count >= (pos + 2))
		    && (path[pos] == const_cpu_to_le16('.'))
		    && (path[pos+1] == const_cpu_to_le16('\\'))) {
			path[1] = const_cpu_to_le16('/');
			pos += 2;
		} else {
			if ((count >= (pos + 3))
			    && (path[pos] == const_cpu_to_le16('.'))
			    &&(path[pos+1] == const_cpu_to_le16('.'))
			    && (path[pos+2] == const_cpu_to_le16('\\'))) {
				path[2] = const_cpu_to_le16('/');
				pos += 3;
				newni = ntfs_dir_parent_inode(curni);
				if (curni != ni)
					ntfs_inode_close(curni);
				curni = newni;
				if (!curni)
					ok = FALSE;
			} else {
				lth = 0;
				while (((pos + lth) < count)
				    && (path[pos + lth] != const_cpu_to_le16('\\')))
					lth++;
				if (lth > 0)
					inum = ntfs_fix_file_name(curni,&path[pos],lth);
				else
					inum = (u64)-1;
				if (!lth
				    || ((curni != ni)
					&& ntfs_inode_close(curni))
				    || (inum == (u64)-1))
					ok = FALSE;
				else {
					curni = ntfs_inode_open(ni->vol, MREF(inum));
					if (!curni)
						ok = FALSE;
					else {
						if (ok && ((pos + lth) < count)) {
							path[pos + lth] = const_cpu_to_le16('/');
							pos += lth + 1;
						} else {
							pos += lth;
							if ((ni->mrec->flags ^ curni->mrec->flags)
							    & MFT_RECORD_IS_DIRECTORY)
								ok = FALSE;
							if (ntfs_inode_close(curni))
								ok = FALSE;
						}
					}
				}
			}
		}
	}

	if (ok && (ntfs_ucstombs(path, count, &target, 0) < 0)) {
		free(target); // needed ?
		target = (char*)NULL;
	}
	return (target);
}