⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 volume.c

📁 上一个上传的有问题,这个是好的。visopsys包括系统内核和GUI的全部SOURCE code ,还包括一些基本的docs文档。里面src子目录对应所有SOURCE code.对于想研究操作系统的朋
💻 C
📖 第 1 页 / 共 4 页
字号:
				"%s\n", strerror(errno));	/*	 * We now initialize the cluster allocator.	 *	 * FIXME: Move this to its own function? (AIA)	 */	// TODO: Make this tunable at mount time. (AIA)	vol->mft_zone_multiplier = 1;	/* Determine the size of the MFT zone. */	mft_zone_size = vol->nr_clusters;	switch (vol->mft_zone_multiplier) {  /* % of volume size in clusters */	case 4:		mft_zone_size >>= 1;			/* 50%   */		break;	case 3:		mft_zone_size = mft_zone_size * 3 >> 3;	/* 37.5% */		break;	case 2:		mft_zone_size >>= 2;			/* 25%   */		break;	/* case 1: */	default:		mft_zone_size >>= 3;			/* 12.5% */		break;	}	/* Setup the mft zone. */	vol->mft_zone_start = vol->mft_zone_pos = vol->mft_lcn;	ntfs_log_debug("mft_zone_pos = 0x%llx\n", (long long)vol->mft_zone_pos);	/*	 * Calculate the mft_lcn for an unmodified NTFS volume (see mkntfs	 * source) and if the actual mft_lcn is in the expected place or even	 * further to the front of the volume, extend the mft_zone to cover the	 * beginning of the volume as well. This is in order to protect the	 * area reserved for the mft bitmap as well within the mft_zone itself.	 * On non-standard volumes we don't protect it as the overhead would be	 * higher than the speed increase we would get by doing it.	 */	mft_lcn = (8192 + 2 * vol->cluster_size - 1) / vol->cluster_size;	if (mft_lcn * vol->cluster_size < 16 * 1024)		mft_lcn = (16 * 1024 + vol->cluster_size - 1) /				vol->cluster_size;	if (vol->mft_zone_start <= mft_lcn)		vol->mft_zone_start = 0;	ntfs_log_debug("mft_zone_start = 0x%llx\n", (long long)vol->mft_zone_start);	/*	 * Need to cap the mft zone on non-standard volumes so that it does	 * not point outside the boundaries of the volume. We do this by	 * halving the zone size until we are inside the volume.	 */	vol->mft_zone_end = vol->mft_lcn + mft_zone_size;	while (vol->mft_zone_end >= vol->nr_clusters) {		mft_zone_size >>= 1;		vol->mft_zone_end = vol->mft_lcn + mft_zone_size;	}	ntfs_log_debug("mft_zone_end = 0x%llx\n", (long long)vol->mft_zone_end);	/*	 * Set the current position within each data zone to the start of the	 * respective zone.	 */	vol->data1_zone_pos = vol->mft_zone_end;	ntfs_log_debug("data1_zone_pos = 0x%llx\n", vol->data1_zone_pos);	vol->data2_zone_pos = 0;	ntfs_log_debug("data2_zone_pos = 0x%llx\n", vol->data2_zone_pos);	/* Set the mft data allocation position to mft record 24. */	vol->mft_data_pos = 24;	/*	 * The cluster allocator is now fully operational.	 */	/* Need to setup $MFT so we can use the library read functions. */	ntfs_log_debug("Loading $MFT... ");	if (ntfs_mft_load(vol) < 0) {		ntfs_log_debug(FAILED);		ntfs_log_perror("Failed to load $MFT");		goto error_exit;	}	ntfs_log_debug(OK);	/* Need to setup $MFTMirr so we can use the write functions, too. */	ntfs_log_debug("Loading $MFTMirr... ");	if (ntfs_mftmirr_load(vol) < 0) {		ntfs_log_debug(FAILED);		ntfs_log_perror("Failed to load $MFTMirr");		goto error_exit;	}	ntfs_log_debug(OK);	return vol;error_exit:	eo = errno;	free(bs);	if (vol)		__ntfs_volume_release(vol);	errno = eo;	return NULL;}/** * ntfs_volume_check_logfile - check logfile on target volume * @vol:	volume on which to check logfile * * Return 0 on success and -1 on error with errno set error code. */static int ntfs_volume_check_logfile(ntfs_volume *vol){	ntfs_inode *ni;	ntfs_attr *na = NULL;	RESTART_PAGE_HEADER *rp = NULL;	int err = 0;	if ((ni = ntfs_inode_open(vol, FILE_LogFile)) == NULL) {		ntfs_log_debug("Failed to open inode FILE_LogFile.\n");		errno = EIO;		return -1;	}	if ((na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0)) == NULL) {		ntfs_log_debug("Failed to open $FILE_LogFile/$DATA\n");		err = EIO;		goto exit;	}	if (!ntfs_check_logfile(na, &rp) || !ntfs_is_logfile_clean(na, rp))		err = EOPNOTSUPP;	if (rp)		free(rp);exit:	if (na)		ntfs_attr_close(na);	ntfs_inode_close(ni);	if (err) {		errno = err;		return -1;	}	return 0;}/** * ntfs_hiberfile_open - Find and open '/hiberfil.sys' * @vol:    An ntfs volume obtained from ntfs_mount * * Return:  inode  Success, hiberfil.sys is valid *	    NULL   hiberfil.sys doesn't exist or some other error occurred */static ntfs_inode *ntfs_hiberfile_open(ntfs_volume *vol){	u64 inode;	ntfs_inode *ni_root;	ntfs_inode *ni_hibr = NULL;	ntfschar   *unicode = NULL;	int unicode_len;	const char *hiberfile = "hiberfil.sys";	if (!vol) {		errno = EINVAL;		return NULL;	}	ni_root = ntfs_inode_open(vol, FILE_root);	if (!ni_root) {		ntfs_log_debug("Couldn't open the root directory.\n");		return NULL;	}	unicode_len = ntfs_mbstoucs(hiberfile, &unicode, 0);	if (unicode_len < 0) {		ntfs_log_perror("Couldn't convert 'hiberfil.sys' to Unicode");		goto out;	}	inode = ntfs_inode_lookup_by_name(ni_root, unicode, unicode_len);	if (inode == (u64)-1) {		ntfs_log_debug("Couldn't find file '%s'.\n", hiberfile);		goto out;	}	inode = MREF(inode);	ni_hibr = ntfs_inode_open(vol, inode);	if (!ni_hibr) {		ntfs_log_debug("Couldn't open inode %lld.\n", (long long)inode);		goto out;	}out:	ntfs_inode_close(ni_root);	free(unicode);	return ni_hibr;}#define NTFS_HIBERFILE_HEADER_SIZE	4096/** * ntfs_volume_check_hiberfile - check hiberfil.sys whether Windows is *                               hibernated on the target volume * @vol:    volume on which to check hiberfil.sys * * Return:  0 if Windows isn't hibernated for sure *         -1 otherwise and errno is set to the appropriate value */static int ntfs_volume_check_hiberfile(ntfs_volume *vol){	ntfs_inode *ni;	ntfs_attr *na = NULL;	int i, bytes_read, ret = -1;	char *buf = NULL;	ni = ntfs_hiberfile_open(vol);	if (!ni) {		if (errno == ENOENT)			return 0;		return -1;	}	buf = malloc(NTFS_HIBERFILE_HEADER_SIZE);	if (!buf) {		ntfs_log_perror("Error allocating memory for hiberfile.sys header");		goto out;	}	na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);	if (!na) {		ntfs_log_perror("Failed to open hiberfil.sys data attribute");		goto out;	}	bytes_read = ntfs_attr_pread(na, 0, NTFS_HIBERFILE_HEADER_SIZE, buf);	if (bytes_read == -1) {		ntfs_log_perror("Failed to read hiberfil.sys");		goto out;	}	if (bytes_read < NTFS_HIBERFILE_HEADER_SIZE) {		ntfs_log_debug("Hibernated non-system partition, refused to "				"mount!\n");		errno = EPERM;		goto out;	}	if (memcmp(buf, "hibr", 4) == 0) {		ntfs_log_debug("Windows is hibernated, refused to mount!\n");		errno = EPERM;		goto out;	}	for (i = 0; i < NTFS_HIBERFILE_HEADER_SIZE; i++) {		if (buf[i]) {			ntfs_log_debug("Windows is hibernated, won't mount!\n");			errno = EPERM;			goto out;		}	}        /* All right, all header bytes are zero */	ret = 0;out:	if (na)		ntfs_attr_close(na);	free(buf);	ntfs_inode_close(ni);	return ret;}/** * ntfs_device_mount - open ntfs volume * @dev:	device to open * @flags:	optional mount flags * * This function mounts an ntfs volume. @dev should describe the device which * to mount as the ntfs volume. * * @flags is an optional second parameter. The same flags are used as for * the mount system call (man 2 mount). Currently only the following flags * are implemented: *	MS_RDONLY	- mount volume read-only *	MS_NOATIME	- do not update access time * * The function opens the device @dev and verifies that it contains a valid * bootsector. Then, it allocates an ntfs_volume structure and initializes * some of the values inside the structure from the information stored in the * bootsector. It proceeds to load the necessary system files and completes * setting up the structure. * * Return the allocated volume structure on success and NULL on error with * errno set to the error code. */ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags){	s64 l;#ifndef NTFS_DISABLE_DEBUG_LOGGING	const char *OK = "OK\n";	const char *FAILED = "FAILED\n";#endif	ntfs_volume *vol;	u8 *m = NULL, *m2 = NULL;	ntfs_attr_search_ctx *ctx = NULL;	ntfs_inode *ni;	ntfs_attr *na;	ATTR_RECORD *a;	VOLUME_INFORMATION *vinf;	ntfschar *vname;	int i, j, eo;	u32 u;	vol = ntfs_volume_startup(dev, flags);	if (!vol) {		ntfs_log_perror("Failed to startup volume");		return NULL;	}	/* Load data from $MFT and $MFTMirr and compare the contents. */	m = (u8*)malloc(vol->mftmirr_size << vol->mft_record_size_bits);	m2 = (u8*)malloc(vol->mftmirr_size << vol->mft_record_size_bits);	if (!m || !m2) {		ntfs_log_perror("Failed to allocate memory");		goto error_exit;	}	l = ntfs_attr_mst_pread(vol->mft_na, 0, vol->mftmirr_size,			vol->mft_record_size, m);	if (l != vol->mftmirr_size) {		if (l == -1)			ntfs_log_perror("Failed to read $MFT");		else {			ntfs_log_debug("Failed to read $MFT, unexpected length "				       "(%d != %lld).\n", vol->mftmirr_size, l);			errno = EIO;		}		goto error_exit;	}	l = ntfs_attr_mst_pread(vol->mftmirr_na, 0, vol->mftmirr_size,			vol->mft_record_size, m2);	if (l != vol->mftmirr_size) {		if (l == -1)			ntfs_log_perror("Failed to read $MFTMirr");		else {			ntfs_log_debug("Failed to read $MFTMirr, unexpected "				       "length (%d != %lld).\n", 				       vol->mftmirr_size, l);			errno = EIO;		}		goto error_exit;	}	ntfs_log_debug("Comparing $MFTMirr to $MFT... ");	for (i = 0; i < vol->mftmirr_size; ++i) {		MFT_RECORD *mrec, *mrec2;		const char *ESTR[12] = { "$MFT", "$MFTMirr", "$LogFile",			"$Volume", "$AttrDef", "root directory", "$Bitmap",			"$Boot", "$BadClus", "$Secure", "$UpCase", "$Extend" };		const char *s;		if (i < 12)			s = ESTR[i];		else if (i < 16)			s = "system file";		else			s = "mft record";		mrec = (MFT_RECORD*)(m + i * vol->mft_record_size);		if (mrec->flags & MFT_RECORD_IN_USE) {			if (ntfs_is_baad_recordp(mrec)) {				ntfs_log_debug("FAILED\n");				ntfs_log_debug("$MFT error: Incomplete multi "						"sector transfer detected in "						"%s.\n", s);				goto io_error_exit;			}			if (!ntfs_is_mft_recordp(mrec)) {				ntfs_log_debug("FAILED\n");				ntfs_log_debug("$MFT error: Invalid mft "						"record for %s.\n", s);				goto io_error_exit;			}		}		mrec2 = (MFT_RECORD*)(m2 + i * vol->mft_record_size);		if (mrec2->flags & MFT_RECORD_IN_USE) {			if (ntfs_is_baad_recordp(mrec2)) {				ntfs_log_debug("FAILED\n");				ntfs_log_debug("$MFTMirr error: Incomplete "						"multi sector transfer "						"detected in %s.\n", s);				goto io_error_exit;			}			if (!ntfs_is_mft_recordp(mrec2)) {				ntfs_log_debug("FAILED\n");				ntfs_log_debug("$MFTMirr error: Invalid mft "						"record for %s.\n", s);				goto io_error_exit;			}		}		if (memcmp(mrec, mrec2, ntfs_mft_record_get_data_size(mrec))) {			ntfs_log_debug(FAILED);			ntfs_log_debug("$MFTMirr does not match $MFT. Run "					"chkdsk.\n");			goto io_error_exit;		}	}	ntfs_log_debug(OK);	free(m2);	free(m);	m = m2 = NULL;	/* Now load the bitmap from $Bitmap. */	ntfs_log_debug("Loading $Bitmap... ");	vol->lcnbmp_ni = ntfs_inode_open(vol, FILE_Bitmap);	if (!vol->lcnbmp_ni) {		ntfs_log_debug(FAILED);		ntfs_log_perror("Failed to open inode");		goto error_exit;	}	/* Get an ntfs attribute for $Bitmap/$DATA. */	vol->lcnbmp_na = ntfs_attr_open(vol->lcnbmp_ni, AT_DATA, AT_UNNAMED, 0);	if (!vol->lcnbmp_na) {		ntfs_log_debug(FAILED);		ntfs_log_perror("Failed to open ntfs attribute");		goto error_exit;	}	/* Done with the $Bitmap mft record. */	ntfs_log_debug(OK);	/* Now load the upcase table from $UpCase. */	ntfs_log_debug("Loading $UpCase... ");	ni = ntfs_inode_open(vol, FILE_UpCase);	if (!ni) {		ntfs_log_debug(FAILED);		ntfs_log_perror("Failed to open inode");		goto error_exit;	}	/* Get an ntfs attribute for $UpCase/$DATA. */	na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);	if (!na) {		ntfs_log_debug(FAILED);		ntfs_log_perror("Failed to open ntfs attribute");		goto error_exit;	}	/*	 * Note: Normally, the upcase table has a length equal to 65536	 * 2-byte Unicode characters but allow for different cases, so no	 * checks done. Just check we don't overflow 32-bits worth of Unicode	 * characters.	 */	if (na->data_size & ~0x1ffffffffULL) {		ntfs_log_debug(FAILED);		ntfs_log_debug("Error: Upcase table is too big (max 32-bit "				"allowed).\n");		errno = EINVAL;		goto error_exit;	}	if (vol->upcase_len != na->data_size >> 1) {		vol->upcase_len = na->data_size >> 1;		/* Throw away default table. */		free(vol->upcase);		vol->upcase = (ntfschar*)malloc(na->data_size);		if (!vol->upcase) {			ntfs_log_debug(FAILED);			ntfs_log_debug("Not enough memory to load $UpCase.\n");			goto error_exit;		}	}	/* Read in the $DATA attribute value into the buffer. */	l = ntfs_attr_pread(na, 0, na->data_size, vol->upcase);	if (l != na->data_size) {		ntfs_log_debug(FAILED);		ntfs_log_debug("Amount of data read does not correspond to expected "				"length!\n");		errno = EIO;		goto error_exit;	}	/* Done with the $UpCase mft record. */	ntfs_log_debug(OK);	ntfs_attr_close(na);	if (ntfs_inode_close(ni))		ntfs_log_perror("Failed to close inode, leaking memory");	/*	 * Now load $Volume and set the version information and flags in the	 * vol structure accordingly.	 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -