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

📄 compress.c

📁 上一个上传的有问题,这个是好的。visopsys包括系统内核和GUI的全部SOURCE code ,还包括一些基本的docs文档。里面src子目录对应所有SOURCE code.对于想研究操作系统的朋
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* Map the next runlist fragment if it is not mapped. */		if (rl->lcn < LCN_HOLE || !rl->length) {			cb_start_vcn = rl->vcn;			rl = ntfs_attr_find_vcn(na, rl->vcn);			if (!rl || rl->lcn < LCN_HOLE || !rl->length)				return TRUE;			/*			 * If the runs were merged need to deal with the			 * resulting partial run so simply restart.			 */			if (rl->vcn < cb_start_vcn)				goto restart;		}		/* If the current run is sparse, the cb is compressed. */		if (rl->lcn == LCN_HOLE)			return TRUE;		/* If the whole cb is not sparse, it is not compressed. */		if (rl->length >= cb_clusters)			return FALSE;		cb_clusters -= rl->length;	};	/* All cb_clusters were not sparse thus the cb is not compressed. */	return FALSE;}/** * ntfs_compressed_attr_pread - read from a compressed attribute * @na:		ntfs attribute to read from * @pos:	byte position in the attribute to begin reading from * @count:	number of bytes to read * @b:		output data buffer * * NOTE:  You probably want to be using attrib.c::ntfs_attr_pread() instead. * * This function will read @count bytes starting at offset @pos from the * compressed ntfs attribute @na into the data buffer @b. * * On success, return the number of successfully read bytes.  If this number * is lower than @count this means that the read reached end of file or that * an error was encountered during the read so that the read is partial. * 0 means end of file or nothing was read (also return 0 when @count is 0). * * On error and nothing has been read, return -1 with errno set appropriately * to the return code of ntfs_pread(), or to EINVAL in case of invalid * arguments. */s64 ntfs_compressed_attr_pread(ntfs_attr *na, s64 pos, s64 count, void *b){	s64 br, to_read, ofs, total, total2;	u64 cb_size_mask;	VCN start_vcn, vcn, end_vcn;	ntfs_volume *vol;	runlist_element *rl;	u8 *dest, *cb, *cb_pos, *cb_end;	u32 cb_size;	int err;	unsigned int nr_cbs, cb_clusters;	ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, pos 0x%llx, count 0x%llx.\n",			(unsigned long long)na->ni->mft_no, na->type,			(long long)pos, (long long)count);	if (!na || !NAttrCompressed(na) || !na->ni || !na->ni->vol || !b ||			pos < 0 || count < 0) {		errno = EINVAL;		return -1;	}	/*	 * Encrypted attributes are not supported.  We return access denied,	 * which is what Windows NT4 does, too.	 */	if (NAttrEncrypted(na)) {		errno = EACCES;		return -1;	}	if (!count)		return 0;	/* Truncate reads beyond end of attribute. */	if (pos + count > na->data_size) {		if (pos >= na->data_size) {			return 0;		}		count = na->data_size - pos;	}	/* If it is a resident attribute, simply use ntfs_attr_pread(). */	if (!NAttrNonResident(na))		return ntfs_attr_pread(na, pos, count, b);	total = total2 = 0;	/* Zero out reads beyond initialized size. */	if (pos + count > na->initialized_size) {		if (pos >= na->initialized_size) {			memset(b, 0, count);			return count;		}		total2 = pos + count - na->initialized_size;		count -= total2;		memset((u8*)b + count, 0, total2);	}	vol = na->ni->vol;	cb_size = na->compression_block_size;	cb_size_mask = cb_size - 1UL;	cb_clusters = na->compression_block_clusters;	/* Need a temporary buffer for each loaded compression block. */	cb = malloc(cb_size);	if (!cb)		return -1;	/* Need a temporary buffer for each uncompressed block. */	dest = malloc(cb_size);	if (!dest) {		err = errno;		free(cb);		errno = err;		return -1;	}	/*	 * The first vcn in the first compression block (cb) which we need to	 * decompress.	 */	start_vcn = (pos & ~cb_size_mask) >> vol->cluster_size_bits;	/* Offset in the uncompressed cb at which to start reading data. */	ofs = pos & cb_size_mask;	/*	 * The first vcn in the cb after the last cb which we need to	 * decompress.	 */	end_vcn = ((pos + count + cb_size - 1) & ~cb_size_mask) >>			vol->cluster_size_bits;	/* Number of compression blocks (cbs) in the wanted vcn range. */	nr_cbs = (end_vcn - start_vcn) << vol->cluster_size_bits >>			na->compression_block_size_bits;	cb_end = cb + cb_size;do_next_cb:	nr_cbs--;	cb_pos = cb;	vcn = start_vcn;	start_vcn += cb_clusters;	/* Check whether the compression block is sparse. */	rl = ntfs_attr_find_vcn(na, vcn);	if (!rl || rl->lcn < LCN_HOLE) {		free(cb);		free(dest);		if (total)			return total;		/* FIXME: Do we want EIO or the error code? (AIA) */		errno = EIO;		return -1;	}	if (rl->lcn == LCN_HOLE) {		/* Sparse cb, zero out destination range overlapping the cb. */		ntfs_log_debug("Found sparse compression block.\n");		to_read = min(count, cb_size - ofs);		memset(b, 0, to_read);		ofs = 0;		total += to_read;		count -= to_read;		b = (u8*)b + to_read;	} else if (!ntfs_is_cb_compressed(na, rl, vcn, cb_clusters)) {		s64 tdata_size, tinitialized_size;		/*		 * Uncompressed cb, read it straight into the destination range		 * overlapping the cb.		 */		ntfs_log_debug("Found uncompressed compression block.\n");		/*		 * Read the uncompressed data into the destination buffer.		 * NOTE: We cheat a little bit here by marking the attribute as		 * not compressed in the ntfs_attr structure so that we can		 * read the data by simply using ntfs_attr_pread().  (-8		 * NOTE: we have to modify data_size and initialized_size		 * temporarily as well...		 */		to_read = min(count, cb_size - ofs);		ofs += vcn << vol->cluster_size_bits;		NAttrClearCompressed(na);		tdata_size = na->data_size;		tinitialized_size = na->initialized_size;		na->data_size = na->initialized_size = na->allocated_size;		do {			br = ntfs_attr_pread(na, ofs, to_read, b);			if (br < 0) {				err = errno;				na->data_size = tdata_size;				na->initialized_size = tinitialized_size;				NAttrSetCompressed(na);				free(cb);				free(dest);				if (total)					return total;				errno = err;				return br;			}			total += br;			count -= br;			b = (u8*)b + br;			to_read -= br;			ofs += br;		} while (to_read > 0);		na->data_size = tdata_size;		na->initialized_size = tinitialized_size;		NAttrSetCompressed(na);		ofs = 0;	} else {		s64 tdata_size, tinitialized_size;		/*		 * Compressed cb, decompress it into the temporary buffer, then		 * copy the data to the destination range overlapping the cb.		 */		ntfs_log_debug("Found compressed compression block.\n");		/*		 * Read the compressed data into the temporary buffer.		 * NOTE: We cheat a little bit here by marking the attribute as		 * not compressed in the ntfs_attr structure so that we can		 * read the raw, compressed data by simply using		 * ntfs_attr_pread().  (-8		 * NOTE: We have to modify data_size and initialized_size		 * temporarily as well...		 */		to_read = cb_size;		NAttrClearCompressed(na);		tdata_size = na->data_size;		tinitialized_size = na->initialized_size;		na->data_size = na->initialized_size = na->allocated_size;		do {			br = ntfs_attr_pread(na,					(vcn << vol->cluster_size_bits) +					(cb_pos - cb), to_read, cb_pos);			if (br < 0) {				err = errno;				na->data_size = tdata_size;				na->initialized_size = tinitialized_size;				NAttrSetCompressed(na);				free(cb);				free(dest);				if (total)					return total;				errno = err;				return br;			}			cb_pos += br;			to_read -= br;		} while (to_read > 0);		na->data_size = tdata_size;		na->initialized_size = tinitialized_size;		NAttrSetCompressed(na);		/* Just a precaution. */		if (cb_pos + 2 <= cb_end)			*(u16*)cb_pos = 0;		ntfs_log_debug("Successfully read the compression block.\n");		if (ntfs_decompress(dest, cb_size, cb, cb_size) < 0) {			err = errno;			free(cb);			free(dest);			if (total)				return total;			errno = err;			return -1;		}		to_read = min(count, cb_size - ofs);		memcpy(b, dest + ofs, to_read);		total += to_read;		count -= to_read;		b = (u8*)b + to_read;		ofs = 0;	}	/* Do we have more work to do? */	if (nr_cbs)		goto do_next_cb;	/* We no longer need the buffers. */	free(cb);	free(dest);	/* Return number of bytes read. */	return total + total2;}

⌨️ 快捷键说明

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