コード例 #1
0
ファイル: ntfs_usnjrnl.c プロジェクト: icaleo/ntfs
/**
 * ntfs_usnjrnl_stamp - stamp the transaction log ($UsnJrnl) on an ntfs volume
 * @vol:	ntfs volume on which to stamp the transaction log
 *
 * Stamp the transaction log ($UsnJrnl) on the ntfs volume @vol and return 0
 * on success and errno on error.
 *
 * This function assumes that the transaction log has already been loaded and
 * consistency checked by a call to ntfs_vfsops.c::ntfs_usnjrnl_load().
 */
errno_t ntfs_usnjrnl_stamp(ntfs_volume *vol)
{
	ntfs_debug("Entering.");
	if (!NVolUsnJrnlStamped(vol)) {
		sle64 j_size, stamp;
		upl_t upl;
		upl_page_info_array_t pl;
		USN_HEADER *uh;
		ntfs_inode *max_ni;
		errno_t err;

		mtx_lock_spin(&vol->usnjrnl_j_ni->size_lock);
		j_size = vol->usnjrnl_j_ni->data_size;
		mtx_unlock_spin(&vol->usnjrnl_j_ni->size_lock);
		max_ni = vol->usnjrnl_max_ni;
		/*
		 * FIXME: Next If statement always false because of
		 * replacing vnode_get() with vhold()
		 */
		vhold(max_ni->vn);
		if (0) {
			ntfs_error(vol->mp, "Failed to get vnode for "
					"$UsnJrnl/$DATA/$Max.");
			return err;
		}
		sx_slock(&max_ni->lock);
		err = ntfs_page_map(max_ni, 0, &upl, &pl, (u8**)&uh, TRUE);
		if (err) {
			ntfs_error(vol->mp, "Failed to read from "
					"$UsnJrnl/$DATA/$Max attribute.");
			vdrop(max_ni->vn);
			return err;
		}
		stamp = ntfs_current_time();
		ntfs_debug("Stamping transaction log ($UsnJrnl): old "
				"journal_id 0x%llx, old lowest_valid_usn "
				"0x%llx, new journal_id 0x%llx, new "
				"lowest_valid_usn 0x%llx.",
				(unsigned long long)
				sle64_to_cpu(uh->journal_id),
				(unsigned long long)
				sle64_to_cpu(uh->lowest_valid_usn),
				(unsigned long long)sle64_to_cpu(stamp),
				(unsigned long long)j_size);
		uh->lowest_valid_usn = cpu_to_sle64(j_size);
		uh->journal_id = stamp;
		ntfs_page_unmap(max_ni, upl, pl, TRUE);
		sx_sunlock(&max_ni->lock);
		vdrop(max_ni->vn);
		/* Set the flag so we do not have to do it again on remount. */
		NVolSetUsnJrnlStamped(vol);
		// TODO: Should we mark any times on the base inode $UsnJrnl
		// for update here?
	}
	ntfs_debug("Done.");
	return 0;
}
コード例 #2
0
ファイル: inode.c プロジェクト: Yardape8000/wiiflow-plus
/**
 * ntfs_inode_update_times - update selected time fields for ntfs inode
 * @ni:		ntfs inode for which update time fields
 * @mask:	select which time fields should be updated
 *
 * This function updates time fields to current time. Fields to update are
 * selected using @mask (see enum @ntfs_time_update_flags for posssible values).
 */
void ntfs_inode_update_times(ntfs_inode *ni, ntfs_time_update_flags mask)
{
	ntfs_time now;

	if (!ni) {
		ntfs_log_error("%s(): Invalid arguments.\n", __FUNCTION__);
		return;
	}

	if ((ni->mft_no < FILE_first_user && ni->mft_no != FILE_root) ||
			NVolReadOnly(ni->vol) || !mask)
		return;

	now = ntfs_current_time();
	if (mask & NTFS_UPDATE_ATIME)
		ni->last_access_time = now;
	if (mask & NTFS_UPDATE_MTIME)
		ni->last_data_change_time = now;
	if (mask & NTFS_UPDATE_CTIME)
		ni->last_mft_change_time = now;

	NInoFileNameSetDirty(ni);
	NInoSetDirty(ni);
}
コード例 #3
0
ファイル: ntfsdecrypt.c プロジェクト: AllardJ/Tomato
/**
 * ntfs_feed_encrypt - Encrypt the contents of stdin to an encrypted file
 * @inode:	An encrypted file's inode structure, as obtained by
 * 		ntfs_inode_open().
 * @fek:	A file encryption key. As obtained by ntfs_inode_fek_get().
 */
static int ntfs_feed_encrypt(ntfs_inode *inode, ntfs_fek *fek)
{
	const int bufsize = 512;
	unsigned char *buffer;
	ntfs_attr *attr;
	s64 bytes_read, written, offset, total;
	unsigned char *b;
	long val;
	int count;
	int i;

	buffer = (unsigned char*)malloc(bufsize);
	if (!buffer)
		return 1;
	attr = ntfs_attr_open(inode, AT_DATA, NULL, 0);
	if (!attr) {
		ntfs_log_error("Cannot feed into a directory.\n");
		goto rejected;
	}
	total = 0;

	if (!(attr->data_flags & ATTR_IS_ENCRYPTED)) {
		ntfs_log_error("The data stream was not encrypted\n");
		goto rejected;
	}
	inode->vol->efs_raw = TRUE;

	if (ntfs_attr_truncate(attr, 0)) {
		ntfs_log_error("Failed to truncate the data stream\n");
		goto rejected;
	}
	offset = 0;
	do {
		bytes_read = fread(buffer, 1, bufsize, stdin);
		if (bytes_read <= 0) {
			if (bytes_read < 0)
				ntfs_log_perror("ERROR: Couldn't read data");
		} else {
			if (bytes_read < bufsize) {
				/* Fill with random data */
				srandom((unsigned int)(sle64_to_cpu(
					inode->last_data_change_time)
					/100000000));
				count = bufsize - bytes_read;
				b = &buffer[bytes_read];
				do {
					val = random();
					switch (count) {
						default :
							*b++ = val;
							val >>= 8;
						case 3 :
							*b++ = val;
							val >>= 8;
						case 2 :
							*b++ = val;
							val >>= 8;
						case 1 :
							*b++ = val;
							val >>= 8;
					}
					count -= 4;
				} while (count > 0);
			}
			if ((i = ntfs_fek_encrypt_sector(fek, buffer, offset))
					< bufsize) {
				ntfs_log_perror("ERROR: Couldn't encrypt all data!");
				ntfs_log_error("%u/%lld/%lld/%lld\n", i,
					(long long)bytes_read, (long long)offset,
					(long long)total);
				break;
			}
		written = ntfs_attr_pwrite(attr, offset, bufsize, buffer);
		if (written != bufsize) {
			ntfs_log_perror("ERROR: Couldn't output all data!");
			break;
		}
		offset += bufsize;
		total += bytes_read;
		}
	} while (bytes_read == bufsize);
	ntfs_attr_truncate(attr, total);
	inode->last_data_change_time = ntfs_current_time();
	NAttrSetEncrypted(attr);
	ntfs_attr_close(attr);
	free(buffer);
	return 0;
rejected :
	free(buffer);
	return (-1);
}
コード例 #4
0
ファイル: inode.c プロジェクト: Yardape8000/wiiflow-plus
int ntfs_inode_set_times(ntfs_inode *ni, const char *value, size_t size,
			int flags)
{
	ntfs_attr_search_ctx *ctx;
	STANDARD_INFORMATION *std_info;
	FILE_NAME_ATTR *fn;
	const u64 *times;
	ntfs_time now;
	int cnt;
	int ret;

	ret = -1;
	if ((size >= 8) && !(flags & XATTR_CREATE)) {
		times = (const u64*)value;
		now = ntfs_current_time();
			/* update the standard information attribute */
		ctx = ntfs_attr_get_search_ctx(ni, NULL);
		if (ctx) {
			if (ntfs_attr_lookup(AT_STANDARD_INFORMATION,
					AT_UNNAMED, 0, CASE_SENSITIVE,
					0, NULL, 0, ctx)) {
				ntfs_log_perror("Failed to get standard info (inode %lld)",
						(long long)ni->mft_no);
			} else {
				std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr +
					le16_to_cpu(ctx->attr->value_offset));
				/*
				 * Mark times set to avoid overwriting
				 * them when the inode is closed.
				 * The inode structure must also be updated
				 * (with loss of precision) because of cacheing.
				 * TODO : use NTFS precision in inode, and
				 * return sub-second times in getattr()
				 */
				set_nino_flag(ni, TimesSet);
				std_info->creation_time = cpu_to_le64(times[0]);
				ni->creation_time
					= std_info->creation_time;
				if (size >= 16) {
					std_info->last_data_change_time = cpu_to_le64(times[1]);
					ni->last_data_change_time
						= std_info->last_data_change_time;
				}
				if (size >= 24) {
					std_info->last_access_time = cpu_to_le64(times[2]);
					ni->last_access_time
						= std_info->last_access_time;
				}
				std_info->last_mft_change_time = now;
				ni->last_mft_change_time = now;
				ntfs_inode_mark_dirty(ctx->ntfs_ino);
				NInoFileNameSetDirty(ni);

				/* update the file names attributes */
				ntfs_attr_reinit_search_ctx(ctx);
				cnt = 0;
				while (!ntfs_attr_lookup(AT_FILE_NAME,
						AT_UNNAMED, 0, CASE_SENSITIVE,
						0, NULL, 0, ctx)) {
					fn = (FILE_NAME_ATTR*)((u8 *)ctx->attr +
						le16_to_cpu(ctx->attr->value_offset));
					fn->creation_time
						= cpu_to_le64(times[0]);
					if (size >= 16)
						fn->last_data_change_time
							= cpu_to_le64(times[1]);
					if (size >= 24)
						fn->last_access_time
							= cpu_to_le64(times[2]);
					fn->last_mft_change_time = now;
					cnt++;
				}
				if (cnt)
					ret = 0;
				else {
					ntfs_log_perror("Failed to get file names (inode %lld)",
						(long long)ni->mft_no);
				}
			}
			ntfs_attr_put_search_ctx(ctx);
		}
	} else
		if (size < 8)
			errno = ERANGE;
		else
			errno = EEXIST;
	return (ret);
}