示例#1
0
static ntfs_index_context *open_object_id_index(ntfs_volume *vol)
{
	u64 inum;
	ntfs_inode *ni;
	ntfs_inode *dir_ni;
	ntfs_index_context *xo;

		/* do not use path_name_to inode - could reopen root */
	dir_ni = ntfs_inode_open(vol, FILE_Extend);
	ni = (ntfs_inode*)NULL;
	if (dir_ni) {
		inum = ntfs_inode_lookup_by_mbsname(dir_ni,"$ObjId");
		if (inum != (u64)-1)
			ni = ntfs_inode_open(vol, inum);
		ntfs_inode_close(dir_ni);
	}
	if (ni) {
		xo = ntfs_index_ctx_get(ni, objid_index_name, 2);
		if (!xo) {
			ntfs_inode_close(ni);
		}
	} else
		xo = (ntfs_index_context*)NULL;
	return (xo);
}
示例#2
0
static ntfs_index_context *open_reparse_index(ntfs_volume *vol)
{
	u64 inum;
	ntfs_inode *ni;
	ntfs_inode *dir_ni;
	ntfs_index_context *xr;

		/* do not use path_name_to inode - could reopen root */
	dir_ni = ntfs_inode_open(vol, FILE_Extend);
	ni = (ntfs_inode*)NULL;
	if (dir_ni) {
		inum = ntfs_inode_lookup_by_mbsname(dir_ni,"$Reparse");
		if (inum != (u64)-1)
			ni = ntfs_inode_open(vol, inum);
		ntfs_inode_close(dir_ni);
	}
	if (ni) {
		xr = ntfs_index_ctx_get(ni, reparse_index_name, 2);
		if (!xr) {
			ntfs_inode_close(ni);
		}
	} else
		xr = (ntfs_index_context*)NULL;
	return (xr);
}
示例#3
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);
}
示例#4
0
static int ntfsrec_cpz_directory_visitor(struct ntfsrec_copy *state, const ntfschar *name, const int name_len, const int name_type, const s64 pos, const MFT_REF mref, const unsigned dt_type) {
    char *local_name = NULL;
    ntfs_inode *inode;
    
    NR_UNUSED(pos);
    
    if ((name_type & FILE_NAME_WIN32_AND_DOS) == FILE_NAME_DOS) {
        return 0;
    }
    
    if (ntfs_ucstombs(name, name_len, &local_name, MAX_PATH_LENGTH) < 0) {
        puts("Error: this filename can't be represented in your locale.");
        return 0;
    }
    
    if (dt_type & NTFS_DT_DIR) {
        ntfs_inode *dir_inode;
        
        if (strcmp(local_name, ".") == 0 || strcmp(local_name, "..") == 0 ||
            strcmp(local_name, "./") == 0 || strcmp(local_name, "../") == 0) {
            free(local_name);
            
            return 0;
        }
        
        dir_inode = ntfs_inode_open(state->volume, mref);
        
        if (dir_inode == NULL) {
            printf("Error: couldn't open folder %s\n", local_name);
            free(local_name);
            return 0;
        }
        
        ntfsrec_recurse_directory(state, dir_inode, local_name);
        
        ntfs_inode_close(dir_inode);
        free(local_name);
        return 0;
    }
    
    inode = ntfs_inode_open(state->volume, mref);
    
    if (inode != NULL) {
        ntfsrec_emit_file(state, inode, local_name);
        ntfs_inode_close(inode);
    } else {
        printf("Error: couldn't open file %s\n", local_name);
    }
    
    free(local_name);
    
    return 0;
}
示例#5
0
/* Restore the DOS name of the @dentry.
 * This closes both @ni and @dir_ni.
 * If either is NULL, then they are opened temporarily.  */
static int
ntfs_3g_restore_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
			 struct wim_dentry *dentry, ntfs_volume *vol)
{
	int ret;
	const char *dos_name;
	size_t dos_name_nbytes;

	/* Note: ntfs_set_ntfs_dos_name() closes both inodes (even if it fails).
	 * And it takes in a multibyte string, even though it translates it to
	 * UTF-16LE internally... which is annoying because we currently have
	 * the UTF-16LE string but not the multibyte string.  */

	ret = utf16le_get_tstr(dentry->short_name, dentry->short_name_nbytes,
			       &dos_name, &dos_name_nbytes);
	if (ret)
		goto out_close;

	if (!dir_ni)
		dir_ni = ntfs_inode_open(vol, dentry->d_parent->d_inode->i_mft_no);
	if (!ni)
		ni = ntfs_inode_open(vol, dentry->d_inode->i_mft_no);
	if (dir_ni && ni) {
		ret = ntfs_set_ntfs_dos_name(ni, dir_ni,
					     dos_name, dos_name_nbytes, 0);
		dir_ni = NULL;
		ni = NULL;
	} else {
		ret = -1;
	}
	utf16le_put_tstr(dos_name);
	if (ret) {
		ERROR_WITH_ERRNO("Failed to set DOS name of \"%s\" in NTFS "
				 "volume", dentry_full_path(dentry));
		ret = WIMLIB_ERR_SET_SHORT_NAME;
		goto out_close;
	}

	/* Unlike most other NTFS-3g functions, ntfs_set_ntfs_dos_name()
	 * changes the directory's last modification timestamp...
	 * Change it back.  */
	return ntfs_3g_restore_timestamps(vol, dentry->d_parent->d_inode);

out_close:
	/* ntfs_inode_close() can take a NULL argument, but it's probably best
	 * not to rely on this behavior.  */
	if (ni)
		ntfs_inode_close(ni);
	if (dir_ni)
		ntfs_inode_close(dir_ni);
	return ret;
}
示例#6
0
status_t
fs_closedir(fs_volume *_vol, fs_vnode *_node, void *cookie)
{
	nspace		*ns = (nspace*)_vol->private_volume;
	vnode		*node = (vnode*)_node->private_node;
	int			result = B_NO_ERROR;
	ntfs_inode	*ni = NULL;

	LOCK_VOL(ns);

	TRACE("fs_closedir - ENTER\n");

	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
			result = ENOENT;
			goto exit;
	}

	fs_ntfs_update_times(_vol, ni, NTFS_UPDATE_ATIME);

exit:
	if (ni)
		ntfs_inode_close(ni);

	TRACE("fs_closedir - EXIT\n");

	UNLOCK_VOL(ns);

	return result;
}
示例#7
0
static int ntfs_dir(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const unsigned long int cluster, file_info_t *dir_list)
{
  ntfs_inode *inode;
  s64 pos;
  struct ntfs_dir_struct *ls=(struct ntfs_dir_struct*)dir_data->private_dir_data;
  ls->dir_list=dir_list;

  inode = ntfs_inode_open (ls->vol, cluster);
  if (!inode) {
    log_error("ntfs_dir: ntfs_inode_open failed\n");
    return -1;
  }

  /*
   * We now are at the final path component.  If it is a file just
   * list it.  If it is a directory, list its contents.
   */
  pos = 0;
  if (inode->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
    if(ntfs_readdir(inode, &pos, ls, (ntfs_filldir_t)ntfs_td_list_entry)<0)
    {
      log_error("ntfs_readdir failed for cluster %lu: %s\n", cluster,
	  strerror(errno));
    }
  }
  else
    log_critical("ntfs_readdir BUG not MFT_RECORD_IS_DIRECTORY\n");
  /* Finished with the inode; release it. */
  ntfs_inode_close(inode);
  td_list_sort(&dir_list->list, filesort);
  return 0;
}
示例#8
0
static int ntfs_drive_letter(ntfs_volume *vol, ntfschar letter)
{
	char defines[NTFS_MAX_NAME_LEN + 5];
	char *drive;
	int ret;
	int sz;
	int olderrno;
	ntfs_inode *ni;

	ret = -1;
	drive = (char*)NULL;
	sz = ntfs_ucstombs(&letter, 1, &drive, 0);
	if (sz > 0) {
		strcpy(defines,mappingdir);
		if ((*drive >= 'a') && (*drive <= 'z'))
			*drive += 'A' - 'a';
		strcat(defines,drive);
		strcat(defines,":");
		olderrno = errno;
		ni = ntfs_pathname_to_inode(vol, NULL, defines);
		if (ni && !ntfs_inode_close(ni))
			ret = 1;
		else
			if (errno == ENOENT) {
				ret = 0;
					/* avoid errno pollution */
				errno = olderrno;
			}
	}
	if (drive)
		free(drive);
	return (ret);
}
示例#9
0
int ntfs_delete_reparse_index(ntfs_inode *ni)
{
	ntfs_index_context *xr;
	ntfs_inode *xrni;
	ntfs_attr *na;
	le32 reparse_tag;
	int res;

	res = 0;
	na = ntfs_attr_open(ni, AT_REPARSE_POINT, AT_UNNAMED, 0);
	if (na) {
			/*
			 * read the existing reparse data (the tag is enough)
			 * and un-index it
			 */
		xr = open_reparse_index(ni->vol);
		if (xr) {
			if (remove_reparse_index(na,xr,&reparse_tag) < 0)
				res = -1;
			xrni = xr->ni;
			ntfs_index_entry_mark_dirty(xr);
			NInoSetDirty(xrni);
			ntfs_index_ctx_put(xr);
			ntfs_inode_close(xrni);
		}
		ntfs_attr_close(na);
	}
	return (res);
}
示例#10
0
int ntfs_delete_object_id_index(ntfs_inode *ni)
{
	ntfs_index_context *xo;
	ntfs_inode *xoni;
	ntfs_attr *na;
	OBJECT_ID_ATTR old_attr;
	int res;

	res = 0;
	na = ntfs_attr_open(ni, AT_OBJECT_ID, AT_UNNAMED, 0);
	if (na) {
			/*
			 * read the existing object id
			 * and un-index it
			 */
		xo = open_object_id_index(ni->vol);
		if (xo) {
			if (remove_object_id_index(na,xo,&old_attr) < 0)
				res = -1;
			xoni = xo->ni;
			ntfs_index_entry_mark_dirty(xo);
			NInoSetDirty(xoni);
			ntfs_index_ctx_put(xo);
			ntfs_inode_close(xoni);
		}
		ntfs_attr_close(na);
	}
	return (res);
}
示例#11
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);
}
示例#12
0
int ntfs_inode_close_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
{
	int res;

	res = ntfs_inode_sync_in_dir(ni, dir_ni);
	if (res) {
		if (errno != EIO)
			errno = EBUSY;
	} else
		res = ntfs_inode_close(ni);
	return (res);
}
示例#13
0
struct XATTRMAPPING *ntfs_xattr_build_mapping(ntfs_volume *vol,
			const char *xattrmap_path)
{
	struct XATTRMAPPING *firstmapping;
	struct XATTRMAPPING *mapping;
	BOOL user_efs;
	BOOL notfound;
	ntfs_inode *ni;
	int fd;

	firstmapping = (struct XATTRMAPPING*)NULL;
	notfound = FALSE;
	if (!xattrmap_path)
		xattrmap_path = XATTRMAPPINGFILE;
	if (xattrmap_path[0] == '/') {
		fd = open(xattrmap_path,O_RDONLY);
		if (fd > 0) {
			firstmapping = ntfs_read_xattr_mapping(basicread, (void*)&fd);
			close(fd);
		} else
			notfound = TRUE;
	} else {
		ni = ntfs_pathname_to_inode(vol, NULL, xattrmap_path);
		if (ni) {
			firstmapping = ntfs_read_xattr_mapping(localread, ni);
			ntfs_inode_close(ni);
		} else
			notfound = TRUE;
	}
	if (notfound && strcmp(xattrmap_path, XATTRMAPPINGFILE)) {
		ntfs_log_early_error("Could not open \"%s\"\n",xattrmap_path);
	}
	if (vol->efs_raw) {
		user_efs = TRUE;
		for (mapping=firstmapping; mapping; mapping=mapping->next)
			if (mapping->xattr == XATTR_NTFS_EFSINFO)
				user_efs = FALSE;
	} else
		user_efs = FALSE;
	if (user_efs) {
		mapping = (struct XATTRMAPPING*)ntfs_malloc(
				sizeof(struct XATTRMAPPING)
				+ strlen(nf_ns_alt_xattr_efsinfo));
		if (mapping) {
			mapping->next = firstmapping;
			mapping->xattr = XATTR_NTFS_EFSINFO;
			strcpy(mapping->name,nf_ns_alt_xattr_efsinfo);
			firstmapping = mapping;
		}
	}
	return (firstmapping);
}
示例#14
0
status_t
fs_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
{
	nspace *ns = (nspace*)_vol->private_volume;
	vnode *node = (vnode*)_node->private_node;
	attrdircookie *cookie = NULL;
	ntfs_inode *ni = NULL;
	ntfs_attr_search_ctx *ctx = NULL;

	status_t result = B_NO_ERROR;

	TRACE("%s - ENTER\n", __FUNCTION__);

	LOCK_VOL(ns);

	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
		result = errno;
		goto exit;
	}

	ctx = ntfs_attr_get_search_ctx(ni, NULL);
	if (ctx == NULL) {
		result = errno;
		goto exit;
	}

	cookie = (attrdircookie*)ntfs_calloc(sizeof(attrdircookie));
	if (cookie == NULL) {
		result = ENOMEM;
		goto exit;
	}

	cookie->inode = ni;
	cookie->ctx = ctx;
	ni = NULL;
	ctx = NULL;
	*_cookie = cookie;
	
exit:

	if (ctx)
		ntfs_attr_put_search_ctx(ctx);
	if (ni)
		ntfs_inode_close(ni);
	
	TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result));
	
	UNLOCK_VOL(ns);
	
	return result;
}
示例#15
0
void ntfsrec_command_cd(struct ntfsrec_command_processor *state, char *arguments) {
    char cwd_buffer[MAX_PATH_LENGTH];
    ntfs_inode *inode;
    
    if (*arguments == '\0') {
        puts("Usage: cd <directory>");
        
        return;
    }
    
    ntfsrec_check_trailing_slash(arguments);
    
    if (ntfsrec_calculate_path(cwd_buffer, MAX_PATH_LENGTH, state->cwd, arguments) == NR_FALSE) {
        printf("Error: invalid path arugment %s\n", arguments);
        return;
    }
    
    inode = ntfs_pathname_to_inode(state->reader->mount.volume, NULL, cwd_buffer);
    
    if (inode == NULL) {
        printf("Error: can't find path %s\n", cwd_buffer);
        
        return;
    }
    
    if (inode->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
        strncpy(state->cwd, cwd_buffer, MAX_PATH_LENGTH);
    } else {
        printf("Error: %s isn't a directory.\n", cwd_buffer);
        ntfs_inode_close(inode);
        
        return;
    }
    
    if (state->cwd_inode != NULL)
        ntfs_inode_close(state->cwd_inode);
    
    state->cwd_inode = inode;
}
示例#16
0
status_t
fs_opendir(fs_volume *_vol, fs_vnode *_node, void** _cookie)
{
	nspace		*ns = (nspace*)_vol->private_volume;
	vnode		*node = (vnode*)_node->private_node;
	dircookie	*cookie = NULL;
	int			result = B_NO_ERROR;
	ntfs_inode	*ni = NULL;

	LOCK_VOL(ns);

	TRACE("fs_opendir - ENTER\n");

	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
		result = ENOENT;
		goto exit;
	}

	if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
		result = EMFILE;
		goto exit;
	}

	cookie = (dircookie*)ntfs_calloc(sizeof(dircookie));
	if (cookie != NULL) {
		cookie->pos = 0;
		cookie->ino = 0;
		cookie->readed = 0;
		cookie->last = 0;
		cookie->name[0] = 0;
		cookie->show_sys_files = ns->show_sys_files;
		*_cookie = (void*)cookie;
	} else
		result = ENOMEM;

exit:
	if (ni)
		ntfs_inode_close(ni);

	TRACE("fs_opendir - EXIT\n");

	UNLOCK_VOL(ns);

	return result;
}
示例#17
0
status_t
fs_free_attrib_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie)
{
	nspace *ns = (nspace*)_vol->private_volume;
	attrcookie *cookie = (attrcookie *)_cookie;

	LOCK_VOL(ns);

	if (cookie->stream)
		ntfs_attr_close(cookie->stream);
	if (cookie->inode)
		ntfs_inode_close(cookie->inode);

	UNLOCK_VOL(ns);

	free(cookie);
	return B_NO_ERROR;
}
示例#18
0
int ntfs_set_ntfs_object_id(ntfs_inode *ni,
			const char *value, size_t size, int flags)
{
	OBJECT_ID_INDEX_KEY key;
	ntfs_inode *xoni;
	ntfs_index_context *xo;
	int res;

	res = 0;
	if (ni && value && (size >= sizeof(GUID))) {
		xo = open_object_id_index(ni->vol);
		if (xo) {
			/* make sure the GUID was not used somewhere */
			memcpy(&key.object_id, value, sizeof(GUID));
			if (ntfs_index_lookup(&key,
					sizeof(OBJECT_ID_INDEX_KEY), xo)) {
				ntfs_index_ctx_reinit(xo);
				res = add_object_id(ni, flags);
				if (!res) {
						/* update value and index */
					res = update_object_id(ni,xo,
						(const OBJECT_ID_ATTR*)value,
						size);
				}
			} else {
					/* GUID is present elsewhere */
				res = -1;
				errno = EEXIST;
			}
			xoni = xo->ni;
			ntfs_index_entry_mark_dirty(xo);
			NInoSetDirty(xoni);
			ntfs_index_ctx_put(xo);
			ntfs_inode_close(xoni);
		} else {
			res = -1;
		}
	} else {
		errno = EINVAL;
		res = -1;
	}
	return (res ? -1 : 0);
}
示例#19
0
/**
 * main - Begin here
 *
 * Start from here.
 *
 * Return:  0  Success, the program worked
 *	    1  Error, something went wrong
 */
int main(int argc, char *argv[])
{
	ntfs_volume *vol;
	ntfs_inode *inode;
	ATTR_TYPES attr;
	int result = 1;

	ntfs_log_set_handler(ntfs_log_handler_stderr);

	if (!parse_options(argc, argv))
		return 1;

	utils_set_locale();

	vol = utils_mount_volume(opts.device, MS_RDONLY |
			(opts.force ? MS_RECOVER : 0));
	if (!vol) {
		ntfs_log_perror("ERROR: couldn't mount volume");
		return 1;
	}

	if (opts.inode != -1)
		inode = ntfs_inode_open(vol, opts.inode);
	else
		inode = ntfs_pathname_to_inode(vol, NULL, opts.file);

	if (!inode) {
		ntfs_log_perror("ERROR: Couldn't open inode");
		return 1;
	}

	attr = AT_DATA;
	if (opts.attr != cpu_to_le32(-1))
		attr = opts.attr;

	result = cat(vol, inode, attr, opts.attr_name, opts.attr_name_len);

	ntfs_inode_close(inode);
	ntfs_umount(vol, FALSE);

	return result;
}
示例#20
0
static int merge_index_data(ntfs_inode *ni,
			const OBJECT_ID_ATTR *objectid_attr,
			OBJECT_ID_ATTR *full_objectid)
{
	OBJECT_ID_INDEX_KEY key;
	struct OBJECT_ID_INDEX *entry;
	ntfs_index_context *xo;
	ntfs_inode *xoni;
	int res;

	res = -1;
	xo = open_object_id_index(ni->vol);
	if (xo) {
		memcpy(&key.object_id,objectid_attr,sizeof(GUID));
		if (!ntfs_index_lookup(&key,
				sizeof(OBJECT_ID_INDEX_KEY), xo)) {
			entry = (struct OBJECT_ID_INDEX*)xo->entry;
			/* make sure inode numbers match */
			if (entry
			    && (MREF(le64_to_cpu(entry->data.file_id))
					== ni->mft_no)) {
				memcpy(&full_objectid->birth_volume_id,
						&entry->data.birth_volume_id,
						sizeof(GUID));
				memcpy(&full_objectid->birth_object_id,
						&entry->data.birth_object_id,
						sizeof(GUID));
				memcpy(&full_objectid->domain_id,
						&entry->data.domain_id,
						sizeof(GUID));
				res = 0;
			}
		}
		xoni = xo->ni;
		ntfs_index_ctx_put(xo);
		ntfs_inode_close(xoni);
	}
	return (res);
}
示例#21
0
/* Restore the timestamps on the NTFS inode corresponding to @inode.  */
static int
ntfs_3g_restore_timestamps(ntfs_volume *vol, const struct wim_inode *inode)
{
	ntfs_inode *ni;
	int res;

	ni = ntfs_inode_open(vol, inode->i_mft_no);
	if (!ni)
		goto fail;

	res = ntfs_3g_set_timestamps(ni, inode);

	if (ntfs_inode_close(ni) || res)
		goto fail;

	return 0;

fail:
	ERROR_WITH_ERRNO("Failed to update timestamps of \"%s\" in NTFS volume",
			 dentry_full_path(inode_first_extraction_dentry(inode)));
	return WIMLIB_ERR_SET_TIMESTAMPS;
}
示例#22
0
文件: fs_func.c 项目: mmanley/Antares
status_t
fs_get_vnode_name(fs_volume *_vol, fs_vnode *_vnode, char *buffer,
	size_t bufferSize)
{
	nspace *ns = (nspace*)_vol->private_volume;
	vnode *node = (vnode*)_vnode->private_node;
	ntfs_inode *ni = NULL;
	status_t result = B_NO_ERROR;

	char path[MAX_PATH];
	char *name;

	LOCK_VOL(ns);

	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
		result = ENOENT;
		goto exit;
	}

	if (utils_inode_get_name(ni, path, MAX_PATH) == 0) {
		result = EINVAL;
		goto exit;
	}

	name = strrchr(path, '/');
	name++;

	strlcpy(buffer, name, bufferSize);

exit:
	if (ni)
		ntfs_inode_close(ni);

	UNLOCK_VOL(ns);

	return result;
}
示例#23
0
void ntfsCloseEntry (ntfs_vd *vd, ntfs_inode *ni)
{
    // Sanity check
    if (!vd) {
        errno = ENODEV;
        return;
    }

    // Lock
    ntfsLock(vd);

    // Sync the entry (if it is dirty)
    if (NInoDirty(ni))
        ntfsSync(vd, ni);

    // Close the entry
    ntfs_inode_close(ni);

    // Unlock
    ntfsUnlock(vd);

    return;
}
示例#24
0
文件: attributes.c 项目: DonCN/haiku
status_t 
fs_read_attrib_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie,
	struct stat *stat)
{
	nspace *ns = (nspace *)_vol->private_volume;
	vnode *node = (vnode *)_node->private_node;
	attrcookie *cookie = (attrcookie *)_cookie;
	ntfs_inode *ni = NULL;
	ntfs_attr *na = NULL;	
	status_t result = B_NO_ERROR;	

	LOCK_VOL(ns);

	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
		result = errno;
		goto exit;
	}
	na = ntfs_attr_open(ni, AT_DATA, cookie->uname, cookie->uname_len);
	if (na == NULL) {
		result = errno;
		goto exit;		
	}

	stat->st_type = cookie->type;
	stat->st_size = na ? na->data_size - sizeof(uint32) : 0;

exit:
	if (na != NULL)
		ntfs_attr_close(na);
	if (ni != NULL)
		ntfs_inode_close(ni);	

	UNLOCK_VOL(ns);
	
	return B_NO_ERROR;
}
示例#25
0
/**
 * PRIVATE: Callback for directory walking
 */
int ntfs_readdir_filler (DIR_ITER *dirState, const ntfschar *name, const int name_len, const int name_type,
                         const s64 pos, const MFT_REF mref, const unsigned dt_type)
{
    ntfs_dir_state *dir = STATE(dirState);
    ntfs_dir_entry *entry = NULL;
    char *entry_name = NULL;

    // Sanity check
    if (!dir || !dir->vd) {
        errno = EINVAL;
        return -1;
    }

    // Ignore DOS file names
    if (name_type == FILE_NAME_DOS) {
        return 0;
    }

    // Preliminary check that this entry can be enumerated (as described by the volume descriptor)
    if (MREF(mref) == FILE_root || MREF(mref) >= FILE_first_user || dir->vd->showSystemFiles) {

        // Convert the entry name to our current local
        if (ntfsUnicodeToLocal(name, name_len, &entry_name, 0) < 0) {
            ntfs_free(entry);
            return -1;
        }

        // If this is not the parent or self directory reference
        if ((strcmp(entry_name, ".") != 0) && (strcmp(entry_name, "..") != 0)) {

            // Open the entry
            ntfs_inode *ni = ntfs_pathname_to_inode(dir->vd->vol, dir->ni, entry_name);
            if (!ni) {
                ntfs_free(entry);
                return -1;
            }

            // Double check that this entry can be emuerated (as described by the volume descriptor)
            if (((ni->flags & FILE_ATTR_HIDDEN) && !dir->vd->showHiddenFiles) ||
                ((ni->flags & FILE_ATTR_SYSTEM) && !dir->vd->showSystemFiles)) {
                ntfs_inode_close(ni);
                return 0;
            }

            // Close the entry
            ntfs_inode_close(ni);

        }

        // Allocate a new directory entry
        entry = ntfs_alloc(sizeof(ntfs_dir_entry));
        if (!entry)
            return -1;

        // Setup the entry
        entry->name = entry_name;
        entry->next = NULL;

        // Link the entry to the directory
        if (!dir->first) {
            dir->first = entry;
        } else {
            ntfs_dir_entry *last = dir->first;
            while (last->next) last = last->next;
            last->next = entry;
        }

    }

    return 0;
}
示例#26
0
status_t
fs_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name,
	int openMode, void **_cookie)
{
	nspace *ns = (nspace*)_vol->private_volume;
	vnode *node = (vnode*)_node->private_node;
	attrcookie *cookie = NULL;
	ntfschar *uname = NULL;
	int ulen;
	ntfs_inode *ni = NULL;
	ntfs_attr *na = NULL;
	status_t result = B_NO_ERROR;

	TRACE("%s - ENTER\n", __FUNCTION__);

	LOCK_VOL(ns);

	if (node == NULL) {
		result = EINVAL;
		goto exit;
	}

	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
		result = errno;
		goto exit;
	}

	// UXA demangling TODO

	// check for EA first... TODO: WRITEME


	// check for a named stream
	if (true) {
		uname = ntfs_calloc(MAX_PATH);
		ulen = ntfs_mbstoucs(name, &uname);
		if (ulen < 0) {
			result = EILSEQ;
			goto exit;
		}

		na = ntfs_attr_open(ni, AT_DATA, uname, ulen);
		if (na) {
			if (openMode & O_TRUNC) {
				if (ntfs_attr_truncate(na, 0))
					result = errno;
			}
		} else {
			result = ENOENT;
			goto exit;
		}
	}


	cookie = (attrcookie*)ntfs_calloc(sizeof(attrcookie));

	if (cookie != NULL) {
		cookie->omode = openMode;
		*_cookie = (void*)cookie;
		cookie->inode = ni;
		cookie->stream = na;
		ni = NULL;
		na = NULL;
	} else
		result = ENOMEM;

exit:
	if (uname)
		free(uname);

	if (na)
		ntfs_attr_close(na);

	if (ni)
		ntfs_inode_close(ni);

	TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result));

	UNLOCK_VOL(ns);

	return result;
}
示例#27
0
/**
 * main - Begin here
 *
 * Start from here.
 *
 * Return:  0  Success, the program worked
 *	    1  Error, something went wrong
 */
int main(int argc, char *argv[])
{
    u8 *pfx_buf;
    char *password;
    ntfs_rsa_private_key rsa_key;
    ntfs_volume *vol;
    ntfs_inode *inode;
    ntfs_fek *fek;
    unsigned pfx_size;
    int res;
    NTFS_DF_TYPES df_type;
    char thumbprint[NTFS_SHA1_THUMBPRINT_SIZE];

#ifdef DEBUG
    ntfs_log_set_handler(ntfs_log_handler_stderr);
#endif

    if (!parse_options(argc, argv))
        return 1;
    utils_set_locale();

    /* Initialize crypto in ntfs. */
    if (ntfs_crypto_init()) {
        ntfs_log_error("Failed to initialize crypto.  Aborting.\n");
        return 1;
    }
    /* Load the PKCS#12 (.pfx) file containing the user's private key. */
    if (ntfs_pkcs12_load_pfxfile(opts.keyfile, &pfx_buf, &pfx_size)) {
        ntfs_log_error("Failed to load key file.  Aborting.\n");
        ntfs_crypto_deinit();
        return 1;
    }
    /* Ask the user for their password. */
    password = getpass("Enter the password with which the private key was "
                       "encrypted: ");
    if (!password) {
        ntfs_log_perror("Failed to obtain user password");
        free(pfx_buf);
        ntfs_crypto_deinit();
        return 1;
    }
    /* Obtain the user's private RSA key from the key file. */
    rsa_key = ntfs_pkcs12_extract_rsa_key(pfx_buf, pfx_size, password,
                                          thumbprint, sizeof(thumbprint), &df_type);
    /* Destroy the password. */
    memset(password, 0, strlen(password));
    /* No longer need the pfx file contents. */
    free(pfx_buf);
    if (!rsa_key) {
        ntfs_log_error("Failed to extract the private RSA key.\n");
        ntfs_crypto_deinit();
        return 1;
    }
    /* Mount the ntfs volume. */
    vol = utils_mount_volume(opts.device, NTFS_MNT_RDONLY |
                             (opts.force ? NTFS_MNT_RECOVER : 0));
    if (!vol) {
        ntfs_log_error("Failed to mount ntfs volume.  Aborting.\n");
        ntfs_rsa_private_key_release(rsa_key);
        ntfs_crypto_deinit();
        return 1;
    }
    /* Open the encrypted ntfs file. */
    if (opts.inode != -1)
        inode = ntfs_inode_open(vol, opts.inode);
    else
        inode = ntfs_pathname_to_inode(vol, NULL, opts.file);
    if (!inode) {
        ntfs_log_error("Failed to open encrypted file.  Aborting.\n");
        ntfs_umount(vol, FALSE);
        ntfs_rsa_private_key_release(rsa_key);
        ntfs_crypto_deinit();
        return 1;
    }
    /* Obtain the file encryption key of the encrypted file. */
    fek = ntfs_inode_fek_get(inode, rsa_key, thumbprint,
                             sizeof(thumbprint), df_type);
    ntfs_rsa_private_key_release(rsa_key);
    if (fek) {
        res = ntfs_cat_decrypt(inode, fek);
        ntfs_fek_release(fek);
    } else {
        ntfs_log_error("Failed to obtain file encryption key.  "
                       "Aborting.\n");
        res = 1;
    }
    ntfs_inode_close(inode);
    ntfs_umount(vol, FALSE);
    ntfs_crypto_deinit();
    return res;
}
示例#28
0
文件: attributes.c 项目: DonCN/haiku
status_t
fs_remove_attrib(fs_volume *_vol, fs_vnode *_node, const char* name)
{
	nspace *ns = (nspace *)_vol->private_volume;
	vnode *node = (vnode *)_node->private_node;
	char ntfs_attr_name[MAX_PATH]={0};
	ntfschar *uname = NULL;
	int ulen;
	ntfs_inode *ni = NULL;		
	status_t result = B_NO_ERROR;

	TRACE("%s - ENTER - name: [%s]\n", __FUNCTION__, name);
	
	if (ns->flags & B_FS_IS_READONLY) {
		ERROR("ntfs is read-only\n");
		return B_READ_ONLY_DEVICE;
	}

	LOCK_VOL(ns);
	
	if (node == NULL) {
		result = EINVAL;
		goto exit;
	}

	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
		result = errno;
		goto exit;
	}		
	
	strcat(ntfs_attr_name, kHaikuAttrPrefix);
	strcat(ntfs_attr_name, name);
	
	uname = ntfs_calloc(MAX_PATH);
	ulen = ntfs_mbstoucs(ntfs_attr_name, &uname);
	if (ulen < 0) {
		result = EILSEQ;
		goto exit;
	}	
	
	if (ntfs_attr_remove(ni, AT_DATA, uname, ulen)) {
		result = ENOENT;
		goto exit;
	}

	if (!(ni->flags & FILE_ATTR_ARCHIVE)) {
		ni->flags |= FILE_ATTR_ARCHIVE;
		NInoFileNameSetDirty(ni);
	}
	notify_attribute_changed(ns->id, MREF(ni->mft_no), name, B_ATTR_REMOVED);
exit:	
	if (uname != NULL)
		free(uname);

	if (ni != NULL)
		ntfs_inode_close(ni);
		
	TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result));

	UNLOCK_VOL(ns);
	
	return result;
}
示例#29
0
文件: attributes.c 项目: DonCN/haiku
status_t
fs_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
	const void *buffer, size_t *_length)
{
	nspace *ns = (nspace *)_vol->private_volume;
	vnode *node = (vnode *)_node->private_node;
	attrcookie *cookie = (attrcookie *)_cookie;
	ntfs_inode *ni = NULL;
	ntfs_attr *na = NULL;
	size_t  size = *_length;
	char *attr_name = NULL;
	char *real_name = NULL;
	int total = 0;
	status_t result = B_NO_ERROR;

	TRACE("%s - ENTER  vnode: %d\n", __FUNCTION__, node->vnid);
	
	if (ns->flags & B_FS_IS_READONLY) {		
		return B_READ_ONLY_DEVICE;
	}

	if (pos < 0) {
		*_length = 0;
		return EINVAL;
	}

	LOCK_VOL(ns);

	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
		result = errno;
		goto exit;
	}
	na = ntfs_attr_open(ni, AT_DATA, cookie->uname, cookie->uname_len);
	if (na == NULL) {
		result = errno;
		goto exit;		
	}		

	pos += sizeof(uint32);

	// it is a named stream
	if (na != NULL) {
		if (cookie->omode & O_APPEND)
			pos = na->data_size;

		if (pos + size > na->data_size) {
			ntfs_mark_free_space_outdated(ns);
			if (ntfs_attr_truncate(na, pos + size))
				size = na->data_size - pos;
			else
				notify_stat_changed(ns->id, MREF(ni->mft_no), B_STAT_SIZE);
		}

		while (size) {
			off_t bytesWritten = ntfs_attr_pwrite(na, pos, size, buffer);
			if (bytesWritten < (s64)size)
				ERROR("%s - ntfs_attr_pwrite returned less bytes than "
					"requested.\n", __FUNCTION__);
			if (bytesWritten <= 0) {
				ERROR("%s - ntfs_attr_pwrite()<=0\n", __FUNCTION__);
				*_length = 0;
				result = EINVAL;
				goto exit;
			}
			size -= bytesWritten;
			pos += bytesWritten;
			total += bytesWritten;
		}

		*_length = total;
	} else {
		*_length = 0;
		result =  EINVAL;
		goto exit;
	}
	
	if (ntfs_ucstombs(na->name, na->name_len, &attr_name, 0) >= 0) {
		if (attr_name != NULL) {
			if(strncmp(attr_name, kHaikuAttrPrefix, strlen(kHaikuAttrPrefix)) !=0 )
				goto exit;
			real_name = attr_name + strlen(kHaikuAttrPrefix);						
			notify_attribute_changed(ns->id, MREF(ni->mft_no),
				real_name, B_ATTR_CHANGED);
			free(attr_name);
		}
	}
		
exit:	
	if (na != NULL)
		ntfs_attr_close(na);
	if (ni != NULL)
		ntfs_inode_close(ni);
		
	TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result));

	UNLOCK_VOL(ns);
	
	return result;
}
示例#30
0
文件: attributes.c 项目: DonCN/haiku
status_t 
fs_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
	void *buffer, size_t *len)
{
	nspace *ns = (nspace *)_vol->private_volume;
	vnode *node = (vnode *)_node->private_node;
	attrcookie *cookie = (attrcookie *)_cookie;
	ntfs_inode *ni = NULL;
	ntfs_attr *na = NULL;
	size_t size = *len;
	int total = 0;
	status_t result = B_NO_ERROR;

	if (pos < 0) {
		*len = 0;
		return EINVAL;
	}

	LOCK_VOL(ns);

	TRACE("%s - ENTER  vnid: %d\n", __FUNCTION__, node->vnid);
	
	ni = ntfs_inode_open(ns->ntvol, node->vnid);
	if (ni == NULL) {
		result = errno;
		goto exit;
	}
	na = ntfs_attr_open(ni, AT_DATA, cookie->uname, cookie->uname_len);
	if (na == NULL) {
		result = errno;
		goto exit;		
	}	
	
	pos += sizeof(uint32);

	// it is a named stream
	if (na != NULL) {
		if (pos + size > na->data_size)
			size = na->data_size - pos;

		while (size) {
			off_t bytesRead = ntfs_attr_pread(na, pos, size, buffer);
			if (bytesRead < (s64)size) {
				ERROR("ntfs_attr_pread returned less bytes than "
					"requested.\n");
			}
			if (bytesRead <= 0) {
				*len = 0;
				result = EINVAL;
				goto exit;
			}
			size -= bytesRead;
			pos += bytesRead;
			total += bytesRead;
		}

		*len = total;
	} else {
		*len = 0;
		result = ENOENT; // TODO
	}

exit:
	if (na != NULL)
		ntfs_attr_close(na);
	if (ni != NULL)
		ntfs_inode_close(ni);
			
	TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result));

	UNLOCK_VOL(ns);
	
	return result;
}