Esempio n. 1
0
static char *search_absolute(ntfs_volume *vol, ntfschar *path,
				int count, BOOL isdir)
{
	ntfs_inode *ni;
	u64 inum;
	char *target;
	int start;
	int len;

	target = (char*)NULL; /* default return */
	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)
			    && (path[start + len] != const_cpu_to_le16('\\')))
				len++;
			inum = ntfs_fix_file_name(ni, &path[start], len);
			ntfs_inode_close(ni);
			ni = (ntfs_inode*)NULL;
			if (inum != (u64)-1) {
				inum = MREF(inum);
				ni = ntfs_inode_open(vol, inum);
				start += len;
				if (start < count)
					path[start++] = const_cpu_to_le16('/');
			}
		} 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->flags & FILE_ATTR_REPARSE_POINT)))
		if (ntfs_ucstombs(path, count, &target, 0) < 0) {
			if (target) {
				free(target);
				target = (char*)NULL;
			}
		}
	if (ni)
		ntfs_inode_close(ni);
	}
	return (target);
}
Esempio n. 2
0
static char *search_absolute(ntfs_volume *vol, ntfschar *path,
				int count, BOOL isdir)
{
	ntfs_inode *ni;
	u64 inum;
	char *target;
	int start;
	int len;

	target = (char*)NULL; /* default return */
	ni = ntfs_inode_open(vol, (MFT_REF)FILE_root);
	if (ni) {
		start = 0;
		do {
			len = 0;
			while (((start + len) < count)
			    && (path[start + len] != const_cpu_to_le16('\\')))
				len++;
			inum = ntfs_fix_file_name(ni, &path[start], len);
			ntfs_inode_close(ni);
			ni = (ntfs_inode*)NULL;
			if (inum != (u64)-1) {
				inum = MREF(inum);
				ni = ntfs_inode_open(vol, inum);
				start += len;
				if (start < count)
					path[start++] = const_cpu_to_le16('/');
			}
		} while (ni
		    && (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
		    && (start < count));
	if (ni
	    && (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY ? isdir : !isdir))
		if (ntfs_ucstombs(path, count, &target, 0) < 0) {
			if (target) {
				free(target);
				target = (char*)NULL;
			}
		}
	if (ni)
		ntfs_inode_close(ni);
	}
	return (target);
}
Esempio n. 3
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);
}
Esempio n. 4
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);
}