📄 bitmap.c
字号:
ntfs_bmp_rollback(bmp); ntfs_attr_close(bmp->attr); free(bmp);}/** * ntfs_bmp_create - Create a representation of a bitmap * @inode: * @type: * @name: * @name_len: * * Description... * * Returns: */struct ntfs_bmp * ntfs_bmp_create(ntfs_inode *inode, ATTR_TYPES type, ntfschar *name, int name_len){ struct ntfs_bmp *bmp; ntfs_attr *attr; if (!inode) return NULL; ntfs_log_trace ("\n"); attr = ntfs_attr_open(inode, type, name, name_len); if (!attr) return NULL; bmp = calloc(1, sizeof(*bmp)); if (!bmp) { ntfs_attr_close(attr); return NULL; } ntfs_log_critical("bmp = %p, attr = %p, inode = %p, attr->ni->mft_no = %lld\n", bmp, attr, inode, MREF(attr->ni->mft_no)); bmp->vol = inode->vol; bmp->attr = attr; bmp->data = NULL; bmp->data_vcn = NULL; bmp->count = 0; return bmp;}/** * ntfs_bmp_add_data - Add a bitmap block to the current cache * @bmp: * @vcn: * @data: * * Description... * * Returns: */int ntfs_bmp_add_data(struct ntfs_bmp *bmp, VCN vcn, u8 *data){ int i = 0; int old; int new; if (!bmp || !data) return -1; ntfs_log_trace ("\n"); old = ROUND_UP(bmp->count, 16); bmp->count++; new = ROUND_UP(bmp->count, 16); if (old != new) { bmp->data = realloc(bmp->data, new * sizeof(*bmp->data)); bmp->data_vcn = realloc(bmp->data_vcn , new * sizeof(*bmp->data_vcn)); } for (i = 0; i < bmp->count-1; i++) if (bmp->data_vcn[i] > vcn) break; if ((bmp->count-i) > 0) { memmove(&bmp->data[i+1], &bmp->data[i], (bmp->count-i) * sizeof(*bmp->data)); memmove(&bmp->data_vcn[i+1], &bmp->data_vcn[i], (bmp->count-i) * sizeof(*bmp->data_vcn)); } bmp->data[i] = data; bmp->data_vcn[i] = vcn; return bmp->count;}/** * ntfs_bmp_get_data - Ask for a bitmap block from the cache * @bmp: * @vcn: * * Description... * * Returns: */u8 * ntfs_bmp_get_data(struct ntfs_bmp *bmp, VCN vcn){ u8 *buffer; int i; int cs; int cb; if (!bmp) return NULL; ntfs_log_trace ("\n"); cs = bmp->vol->cluster_size; cb = bmp->vol->cluster_size_bits; // XXX range check against vol,attr // never compressed, so data = init vcn >>= (cb + 3); // convert to bitmap clusters for (i = 0; i < bmp->count; i++) { if (vcn == bmp->data_vcn[i]) { //ntfs_log_debug("reusing bitmap cluster %lld\n", vcn); return bmp->data[i]; } } buffer = calloc(1, cs); // XXX could be smaller if attr size < cluster size if (!buffer) return NULL; //ntfs_log_debug("loading from bitmap cluster %lld\n", vcn); //ntfs_log_debug("loading from bitmap byte %lld\n", vcn<<cb); if (ntfs_attr_pread(bmp->attr, vcn<<cb, cs, buffer) < 0) { free(buffer); return NULL; } ntfs_bmp_add_data(bmp, vcn, buffer); // XXX retval return buffer;}/** * ntfs_bmp_set_range - Set a range of bits in the bitmap * @bmp: * @vcn: * @length: * @value: * * Description... * * Returns: */int ntfs_bmp_set_range(struct ntfs_bmp *bmp, VCN vcn, s64 length, int value){ // shouldn't all the vcns be lcns? s64 i; u8 *buffer; int csib; // cluster size in bits int block_start, block_finish; // rename to c[sf] (rename to clust_) int vcn_start, vcn_finish; // rename to v[sf] int byte_start, byte_finish; // rename to b[sf] u8 mask_start, mask_finish; // rename to m[sf] s64 a,b; if (!bmp) return -1; ntfs_log_trace ("vcn %lld, length %lld, value %d\n", vcn, length, value); if (value) value = 0xFF; csib = bmp->vol->cluster_size << 3; vcn_start = vcn; vcn_finish = vcn + length - 1; //ntfs_log_debug("vcn_start = %d, vcn_finish = %d\n", vcn_start, vcn_finish); a = ROUND_DOWN(vcn_start, csib); b = ROUND_DOWN(vcn_finish, csib) + 1; //ntfs_log_debug("a = %lld, b = %lld\n", a, b); for (i = a; i < b; i += csib) { //ntfs_log_debug("ntfs_bmp_get_data %lld\n", i); buffer = ntfs_bmp_get_data(bmp, i); if (!buffer) return -1; block_start = i; block_finish = block_start + csib - 1; mask_start = (0xFF << (vcn_start & 7)); mask_finish = (0xFF >> (7 - (vcn_finish & 7))); if ((vcn_start >= block_start) && (vcn_start <= block_finish)) { byte_start = (vcn_start - block_start) >> 3; } else { byte_start = 0; mask_start = 0xFF; } if ((vcn_finish >= block_start) && (vcn_finish <= block_finish)) { byte_finish = (vcn_finish - block_start) >> 3; } else { byte_finish = bmp->vol->cluster_size - 1; mask_finish = 0xFF; } if ((byte_finish - byte_start) > 1) { memset(buffer+byte_start+1, value, byte_finish-byte_start-1); } else if (byte_finish == byte_start) { mask_start &= mask_finish; mask_finish = 0x00; } if (value) { buffer[byte_start] |= mask_start; buffer[byte_finish] |= mask_finish; } else { buffer[byte_start] &= (~mask_start); buffer[byte_finish] &= (~mask_finish); } }#if 1 ntfs_log_debug("Modified: inode %lld, ", bmp->attr->ni->mft_no); switch (bmp->attr->type) { case AT_BITMAP: ntfs_log_debug("$BITMAP"); break; case AT_DATA: ntfs_log_debug("$DATA"); break; default: break; } ntfs_log_debug(" vcn %lld-%lld\n", vcn>>12, (vcn+length-1)>>12);#endif return 1;}/** * ntfs_bmp_find_last_set - Find the last set bit in the bitmap * @bmp: * * Description... * * Returns: */s64 ntfs_bmp_find_last_set(struct ntfs_bmp *bmp){ s64 clust_count; s64 byte_count; s64 clust; int byte; int bit; int note; u8 *buffer; if (!bmp) return -2; ntfs_log_trace ("\n"); // find byte size of bmp // find cluster size of bmp byte_count = bmp->attr->data_size; clust_count = ROUND_UP(byte_count, bmp->vol->cluster_size) >> bmp->vol->cluster_size_bits; //ntfs_log_debug("bitmap = %lld bytes\n", byte_count); //ntfs_log_debug("bitmap = %lld buffers\n", clust_count); // for each cluster backwards for (clust = clust_count-1; clust >= 0; clust--) { //ntfs_log_debug("cluster %lld\n", clust); //ntfs_log_debug("get vcn %lld\n", clust << (bmp->vol->cluster_size_bits + 3)); buffer = ntfs_bmp_get_data(bmp, clust << (bmp->vol->cluster_size_bits + 3)); //utils_dump_mem(buffer, 0, 8, DM_NO_ASCII); if (!buffer) return -2; if ((clust == (clust_count-1) && ((byte_count % bmp->vol->cluster_size) != 0))) { byte = byte_count % bmp->vol->cluster_size; } else { byte = bmp->vol->cluster_size; } //ntfs_log_debug("start byte = %d\n", byte); // for each byte backward for (byte--; byte >= 0; byte--) { //ntfs_log_debug("\tbyte %d (%d)\n", byte, buffer[byte]); // for each bit shift up note = -1; for (bit = 7; bit >= 0; bit--) { //ntfs_log_debug("\t\tbit %d (%d)\n", (1<<bit), buffer[byte] & (1<<bit)); if (buffer[byte] & (1<<bit)) { // if set, keep note note = bit; break; } } if (note >= 0) { // if note, return value //ntfs_log_debug("match %lld (c=%lld,b=%d,n=%d)\n", (((clust << bmp->vol->cluster_size_bits) + byte) << 3) + note, clust, byte, note); return ((((clust << bmp->vol->cluster_size_bits) + byte) << 3) + note); } } } return -1;}/** * ntfs_bmp_find_space - Find an unused block of bits in a bitmap * @bmp: * @start: * @size: * * Description... * * Returns: */int ntfs_bmp_find_space(struct ntfs_bmp *bmp, LCN start, long size){ if (!bmp) return 0; ntfs_log_trace ("\n"); start = 0; size = 0; /* bmp find space - uncached bmp's $Bitmap/$DATA free space on volume dir/$BITMAP free index record $MFT/$BITMAP free record in mft */ return 0;}#endif /* NTFS_RICH */#endif /* __VISOPSYS__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -