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

📄 ntfsresize.c

📁 上一个上传的有问题,这个是好的。visopsys包括系统内核和GUI的全部SOURCE code ,还包括一些基本的docs文档。里面src子目录对应所有SOURCE code.对于想研究操作系统的朋
💻 C
📖 第 1 页 / 共 5 页
字号:
		  {			err_printf(resize, "ntfs_rl_truncate failed");			return (-1);		  }	return (0);}/** * bitmap_file_data_fixup * * $Bitmap can overlap the end of the volume. Any bits in this region * must be set. This region also encompasses the backup boot sector. */static void bitmap_file_data_fixup(s64 cluster, struct bitmap *bm){	for (; cluster < bm->size << 3; cluster++)		ntfs_bit_set(bm->bm, (u64)cluster, 1);}/** * truncate_badclust_bad_attr * * The metadata file $BadClus needs to be shrunk. * * FIXME: this function should go away and instead using a generalized * "truncate_bitmap_data_attr()" */static int truncate_badclust_bad_attr(ntfs_resize_t *resize){	ATTR_RECORD *a;	runlist *rl_bad;	s64 nr_clusters = resize->new_volume_size;	ntfs_volume *vol = resize->vol;	a = resize->ctx->attr;	if (!a->non_resident)	  {		/* FIXME: handle resident attribute value */		err_printf(resize, "Resident attribute in $BadClust isn't supported!");		return (-1);	  }	if (!(rl_bad = ntfs_mapping_pairs_decompress(vol, a, NULL)))	  {		err_printf(resize, "ntfs_mapping_pairs_decompress failed");		return (-1);	  }	if (rl_truncate(resize, &rl_bad, nr_clusters) < 0)		return (-1);	a->highest_vcn = cpu_to_le64(nr_clusters - 1LL);	a->allocated_size = cpu_to_le64(nr_clusters * vol->cluster_size);	a->data_size = cpu_to_le64(nr_clusters * vol->cluster_size);	if (replace_attribute_runlist(resize, vol, resize->ctx, rl_bad) < 0)		return (-1);	free(rl_bad);	return (0);}/** * realloc_bitmap_data_attr * * Reallocate the metadata file $Bitmap.  It must be large enough for one bit * per cluster of the shrunken volume.  Also it must be a of 8 bytes in size. */static int realloc_bitmap_data_attr(ntfs_resize_t *resize,				     runlist **rl,				     s64 nr_bm_clusters){	s64 i;	ntfs_volume *vol = resize->vol;	ATTR_RECORD *a = resize->ctx->attr;	s64 new_size = resize->new_volume_size;	struct bitmap *bm = &resize->lcn_bitmap;	if (!(*rl = ntfs_mapping_pairs_decompress(vol, a, NULL)))	  {		err_printf(resize, "ntfs_mapping_pairs_decompress failed");		return (-1);	  }	release_bitmap_clusters(bm, *rl);	free(*rl);	for (i = vol->nr_clusters; i < new_size; i++)		ntfs_bit_set(bm->bm, i, 0);	if (!(*rl = alloc_cluster(resize, bm, nr_bm_clusters, new_size, 0)))	  {		err_printf(resize, "Couldn't allocate $Bitmap clusters");		return (-1);	  }	return (0);}static int realloc_lcn_bitmap(ntfs_resize_t *resize, s64 bm_bsize){	u8 *tmp;	if (!(tmp = realloc(resize->lcn_bitmap.bm, bm_bsize)))	  {		err_printf(resize, "realloc failed");		return (-1);	  }	resize->lcn_bitmap.bm = tmp;	resize->lcn_bitmap.size = bm_bsize;	bitmap_file_data_fixup(resize->new_volume_size, &resize->lcn_bitmap);	return (0);}/** * truncate_bitmap_data_attr */static int truncate_bitmap_data_attr(ntfs_resize_t *resize){	ATTR_RECORD *a;	runlist *rl;	s64 bm_bsize, size;	s64 nr_bm_clusters;	ntfs_volume *vol = resize->vol;	a = resize->ctx->attr;	if (!a->non_resident)	  {		/* FIXME: handle resident attribute value */		err_printf(resize, "Resident attribute in $Bitmap isn't supported!");		return (-1);	  }	bm_bsize = nr_clusters_to_bitmap_byte_size(resize->new_volume_size);	nr_bm_clusters = rounded_up_division(bm_bsize, vol->cluster_size);	if (resize->shrink) {		if (realloc_bitmap_data_attr(resize, &rl, nr_bm_clusters) < 0)			return (-1);		if (realloc_lcn_bitmap(resize, bm_bsize) < 0)			return (-1);	} else {		if (realloc_lcn_bitmap(resize, bm_bsize) < 0)			return (-1);		if (realloc_bitmap_data_attr(resize, &rl, nr_bm_clusters) < 0)			return (-1);	}	a->highest_vcn = cpu_to_le64(nr_bm_clusters - 1LL);	a->allocated_size = cpu_to_le64(nr_bm_clusters * vol->cluster_size);	a->data_size = cpu_to_le64(bm_bsize);	a->initialized_size = cpu_to_le64(bm_bsize);	if (replace_attribute_runlist(resize, vol, resize->ctx, rl) < 0)		return (-1);	/*	 * FIXME: update allocated/data sizes and timestamps in $FILE_NAME	 * attribute too, for now chkdsk will do this for us.	 */	size = ntfs_rl_pwrite(vol, rl, 0, bm_bsize, resize->lcn_bitmap.bm);	if (bm_bsize != size) {		if (size == -1)			err_printf(resize, "Couldn't write $Bitmap");		else			err_printf(resize, "Couldn't write full $Bitmap file (%lld from %lld)",				(long long)size, (long long)bm_bsize);		return (-1);	}	free(rl);	return (0);}/** * lookup_data_attr * * Find the $DATA attribute (with or without a name) for the given MFT reference * (inode number). */static int lookup_data_attr(ntfs_resize_t *resize, ntfs_volume *vol,			     MFT_REF mref,			     const char *aname,			     ntfs_attr_search_ctx **ctx){	ntfs_inode *ni;	ntfschar *ustr = NULL;	int len = 0;	if (!(ni = ntfs_inode_open(vol, mref)))	  {		err_printf(resize, "ntfs_open_inode failed");		return (-1);	  }	if (!(*ctx = attr_get_search_ctx(resize, ni, NULL)))	  {		return (-1);	  }	if ((ustr = ntfs_str2ucs(aname, &len)) == NULL) {		err_printf(resize, "Couldn't convert '%s' to Unicode", aname);		return (-1);	}	if (ntfs_attr_lookup(AT_DATA, ustr, len, 0, 0, NULL, 0, *ctx))	  {		err_printf(resize, "ntfs_lookup_attr failed");		return (-1);	  }	ntfs_ucsfree(ustr);	return (0);}static int check_bad_sectors(ntfs_resize_t *resize, ntfs_volume *vol){	ntfs_attr_search_ctx *ctx;	ntfs_inode *base_ni;	runlist *rl;	s64 i, badclusters = 0;	progress_message(resize, "Checking for bad sectors");	if (lookup_data_attr(resize, vol, FILE_BadClus, "$Bad", &ctx) != 0)		return (-1);	base_ni = ctx->base_ntfs_ino;	if (!base_ni)		base_ni = ctx->ntfs_ino;	if (NInoAttrList(base_ni)) {		err_printf(resize, "Hopelessly many bad sectors has been detected!");		err_printf(resize, "%s", many_bad_sectors_msg);		return (-1);	}	if (!ctx->attr->non_resident)	  {		err_printf(resize, "Resident attribute in $BadClust! Please report to "			 "%s", NTFS_DEV_LIST);		return (-1);	  }	/* 	 * FIXME: The below would be partial for non-base records in the	 * not yet supported multi-record case. Alternatively use audited	 * ntfs_attr_truncate after an umount & mount.	 */	if (!(rl = ntfs_mapping_pairs_decompress(vol, ctx->attr, NULL)))	  {		err_printf(resize, "Decompressing $BadClust:$Bad mapping pairs failed");		return (-1);	  }	for (i = 0; rl[i].length; i++) {		/* CHECKME: LCN_RL_NOT_MAPPED check isn't needed */		if (rl[i].lcn == LCN_HOLE || rl[i].lcn == LCN_RL_NOT_MAPPED)			continue;		badclusters += rl[i].length;		err_printf(resize, "Bad cluster: %llx - %llx (%lld)\n",				 rl[i].lcn, rl[i].lcn + rl[i].length - 1,				 rl[i].length);	}	if (badclusters) {		err_printf(resize, "This software has detected that the\n"			   "disk has at least %lld bad sector%s.",		       badclusters, badclusters - 1 ? "s" : "");		if (!opt.badsectors) {			err_printf(resize, "%s", bad_sectors_warning_msg);			return (-1);		} else			err_printf(resize, "Bad sectors can cause reliability\n"			       "problems and massive data loss!!!");	}	free(rl);	ntfs_attr_put_search_ctx(ctx);	return badclusters;}/** * truncate_badclust_file * * Shrink the $BadClus file to match the new volume size. */static int truncate_badclust_file(ntfs_resize_t *resize){	progress_message(resize, "Updating $BadClust file");	if (lookup_data_attr(resize, resize->vol, FILE_BadClus, "$Bad", &resize->ctx) != 0)		return (-1);	/* FIXME: sanity_check_attr(ctx->attr); */	if (truncate_badclust_bad_attr(resize) < 0)		return (-1);	if (write_mft_record(resize, resize->vol, resize->ctx->ntfs_ino->mft_no,			     resize->ctx->mrec))	  {		err_printf(resize, "Couldn't update $BadClust");		return (-1);	  }	ntfs_attr_put_search_ctx(resize->ctx);	return (0);}/** * truncate_bitmap_file * * Shrink the $Bitmap file to match the new volume size. */static int truncate_bitmap_file(ntfs_resize_t *resize){	progress_message(resize, "Updating $Bitmap file");	if (lookup_data_attr(resize, resize->vol, FILE_Bitmap, NULL, &resize->ctx) != 0)		return (-1);	if (truncate_bitmap_data_attr(resize) < 0)		return (-1);	if (write_mft_record(resize, resize->vol, resize->ctx->ntfs_ino->mft_no,			     resize->ctx->mrec))	  {		err_printf(resize, "Couldn't update $Bitmap");		return (-1);	  }	ntfs_attr_put_search_ctx(resize->ctx);	return (0);}/** * setup_lcn_bitmap * * Allocate a block of memory with one bit for each cluster of the disk. * All the bits are set to 0, except those representing the region beyond the * end of the disk. */static int setup_lcn_bitmap(ntfs_resize_t *resize, struct bitmap *bm, s64 nr_clusters){	progress_message(resize, "Set up LCN bitmap");	/* Determine lcn bitmap byte size and allocate it. */	bm->size = rounded_up_division(nr_clusters, 8);	if (!(bm->bm = (unsigned char *)calloc(1, bm->size)))		return -1;	bitmap_file_data_fixup(nr_clusters, bm);	return 0;}/** * update_bootsector * * FIXME: should be done using ntfs_* functions */static int update_bootsector(ntfs_resize_t *r){	NTFS_BOOT_SECTOR bs;	s64  bs_size = sizeof(NTFS_BOOT_SECTOR);	ntfs_volume *vol = r->vol;	progress_message(r, "Updating Boot record");	if (vol->dev->d_ops->seek(vol->dev, 0, SEEK_SET) == (off_t)-1)	  {		err_printf(r, "lseek failed");		return (-1);	  }	if (vol->dev->d_ops->read(vol->dev, &bs, bs_size) == -1)	  {		err_printf(r, "read() error");		return (-1);	  }	bs.number_of_sectors = cpu_to_sle64(r->new_volume_size *			bs.bpb.sectors_per_cluster);	if (r->mftmir_old) {		if (copy_clusters(r, r->mftmir_rl.lcn, r->mftmir_old,			      r->mftmir_rl.length) < 0)			return (-1);		bs.mftmirr_lcn = cpu_to_le64(r->mftmir_rl.lcn);	}	if (vol->dev->d_ops->seek(vol->dev, 0, SEEK_SET) == (off_t)-1)	  {		err_printf(r, "lseek failed");		return (-1);	  }//	if (!opt.ro_flag)		if (vol->dev->d_ops->write(vol->dev, &bs, bs_size) == -1)		  {			err_printf(r, "write() error");			return (-1);		  }	return (0);}#ifndef __VISOPSYS__/** * vol_size */static s64 vol_size(ntfs_volume *v, s64 nr_clusters){	/* add one sector_size for the backup boot sector */	return nr_clusters * v->cluster_size + v->sector_size;}/** * print_vol_size * * Print the volume size in bytes and decimal megabytes. */static void print_vol_size(const char *str, s64 bytes){	printf("%s: %lld bytes (%lld MB)\n", str, (long long)bytes,			(long long)rounded_up_division(bytes, NTFS_MBYTE));}/** * print_disk_usage * * Display the amount of disk space in use. */static void print_disk_usage(ntfs_volume *vol, s64 nr_used_clusters){	s64 total, used;	total = vol->nr_clusters * vol->cluster_size;	used = nr_used_clusters * vol->cluster_size;	/* WARNING: don't modify the text, external tools grep for it */	printf("Space in use       : %lld MB (%.1f%%)\n",	       (long long)rounded_up_division(used, NTFS_MBYTE),	       100.0 * ((float)used / total));}static void print_num_of_relocations(ntfs_resize_t *resize){	s64 relocations = resize->relocations * resize->vol->cluster_size;	printf("Needed relocations : %lld (%lld MB)\n",			(long long)resize->relocations, (long long)			rounded_up_division(relocations, NTFS_MBYTE));}#endif /* __VISOPSYS__ *//** * mount_volume * * First perform some checks to determine if the volume is already mounted, or * is dirty (Windows wasn't shutdown properly).  If everything is OK, then mount * the volume (load the metadata into memory). */static ntfs_volume *mount_volume(ntfs_resize_t *resize){	unsigned long mntflag;	ntfs_volume *vol = NULL;	progress_message(resize, "Mounting volume");	if (ntfs_check_if_mounted(opt.volume, &mntflag)) {		err_printf(resize, "Failed to check '%s' mount state", opt.volume);		return (NULL);	}	if (mntflag & NTFS_MF_MOUNTED) {		if (!(mntflag & NTFS_MF_READONLY))			err_printf(resize, "Device '%s' is mounted read-write.  "				   "You must unmount it first.", opt.volume);		else			err_printf(resize, "Device '%s' is mounted.  "				   "You must unmount it first.", opt.volume);		return (NULL);	}	if (!(vol = ntfs_mount(opt.volume, MS_NOATIME))) {		int err = errno;		static char *ERRMESS = "Opening '%s' as NTFS failed.  %s";		if (err == EINVAL)			err_printf(resize, ERRMESS, opt.volume,				   invalid_ntfs_msg);		else if (err == EIO)			err_printf(resize, ERRMESS, opt.volume,				   corrupt_volume_msg);		else if (err == EPERM)			err_printf(resize, ERRMESS, opt.volume,				   hibernated_volume_msg);		else if (err == EOPNOTSUPP)			err_printf(resize, ERRMESS, opt.volume,				   unclean_journal_msg);		else if (err == EBUSY)			err_printf(resize, ERRMESS, opt.volume,				   opened_volume_msg);		else			err_printf(resize, ERRMESS, opt.volume, "Unknown error.");		return (NULL);	}	if (vol->flags & VOLUME_IS_DIRTY)		if (opt.force-- <= 0)		  {			err_printf(resize, "Volume is scheduled for check.  Run chkdsk /f"				 " and please try again, or see option -f.");			return (NULL);		  }	if (NTFS_MAX_CLUSTER_SIZE < vol->cluster_size)	  {		err_printf(resize, "Cluster size %u is too large!",			(unsigned int)vol->cluster_size);		return (NULL);	  }	progress_message(resize, "Device name: %s", opt.volume);	progress_message(resize, "NTFS volume version: %d.%d", vol->major_ver, vol->minor_ver);	if (ntfs_versio

⌨️ 快捷键说明

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