From 6b1670837cb64fa8c0426941a54f09be22bc1206 Mon Sep 17 00:00:00 2001 From: "flatcap.org!ntfs" Date: Sat, 26 Jun 2004 10:35:23 +0000 Subject: [PATCH] make bitmap alterations in memory (Logical change 1.442) --- ntfsprogs/ntfsrm.c | 308 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 295 insertions(+), 13 deletions(-) diff --git a/ntfsprogs/ntfsrm.c b/ntfsprogs/ntfsrm.c index ba3815f9..6e38bbc2 100644 --- a/ntfsprogs/ntfsrm.c +++ b/ntfsprogs/ntfsrm.c @@ -201,20 +201,15 @@ static VCN ntfs_ie_get_vcn (INDEX_ENTRY *ie); static INDEX_ENTRY * ntfs_ie_set_name (INDEX_ENTRY *ie, ntfschar *name, int namelen, FILE_NAME_TYPE_FLAGS nametype); /** - * struct bmp_page + * struct ntfs_bmp + * a cache for either dir/$BITMAP, $MFT/$BITMAP or $MFT/$Bitmap */ -struct bmp_page { - u8 *data; - VCN vcn; -}; - -/** - * struct mft_bitmap - */ -struct mft_bitmap { - ntfs_attr *bmp; - struct bmp_page **pages; - int count; +struct ntfs_bmp { + ntfs_attr *attr; + u8 **data; + VCN *data_vcn; + int count; + //int cluster_size; }; /** @@ -302,6 +297,225 @@ static void ntfs_dt_print (struct ntfs_dt *dt, int indent) } +/** + * ntfs_bmp_free + */ +static void ntfs_bmp_free (struct ntfs_bmp *bmp) +{ + int i; + + if (!bmp) + return; + + for (i = 0; i < bmp->count; i++) + free (bmp->data[i]); + + ntfs_attr_close (bmp->attr); + + free (bmp->data); + free (bmp->data_vcn); + free (bmp); +} + +/** + * ntfs_bmp_alloc + */ +static struct ntfs_bmp * ntfs_bmp_alloc (ntfs_inode *inode, ATTR_TYPES type, ntfschar *name, int name_len) +{ + struct ntfs_bmp *bmp; + ntfs_attr *attr; + + if (!inode) + return NULL; + + attr = ntfs_attr_open (inode, type, name, name_len); + if (!attr) + return NULL; + + bmp = calloc (1, sizeof (*bmp)); + if (!bmp) + return NULL; + + bmp->attr = attr; + bmp->data = calloc (16, sizeof (*bmp->data)); + bmp->data_vcn = calloc (16, sizeof (*bmp->data_vcn)); + bmp->count = 0; + + if (!bmp->data || !bmp->data_vcn) { + ntfs_bmp_free (bmp); + return NULL; + } + + return bmp; +} + +/** + * ntfs_bmp_add_data + */ +static 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; + + old = ((bmp->count + 15) & ~15); + bmp->count++; + new = ((bmp->count + 15) & ~15); + + 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 + */ +static u8 * ntfs_bmp_get_data (struct ntfs_bmp *bmp, VCN vcn) +{ + u8 *buffer; + int i; + VCN begin; + VCN end; + + if (!bmp) + return NULL; + + for (i = 0; i < bmp->count; i++) { + begin = (bmp->data_vcn[i] >> 3) & (~(512-1)); + end = begin + (512 << 3); + if ((vcn >= begin) && (vcn < end)) { + //printf ("%lld, %lld, %lld\n", begin, vcn, end); + return bmp->data[i]; + } + } + + buffer = malloc (512); + if (!buffer) + return NULL; + + begin = (vcn>>3) & (~(512-1)); + //printf ("loading from offset %lld\n", begin); + if (ntfs_attr_pread (bmp->attr, begin, 512, buffer) < 0) { + free (buffer); + return NULL; + } + + ntfs_bmp_add_data (bmp, vcn, buffer); + return buffer; +} + +/** + * ntfs_bmp_set_range + */ +static int ntfs_bmp_set_range (struct ntfs_bmp *bmp, VCN vcn, u64 length, int value) +{ + u64 i; + u8 *buffer; + VCN begin; + VCN end; + int start; + int finish; + u8 sta_part; + u8 fin_part; + + if (!bmp) + return -1; + + //printf ("\n"); + //printf ("set range: %lld - %lld\n", vcn, vcn+length-1); + + for (i = vcn; i < (vcn+length); i += 4096) { + buffer = ntfs_bmp_get_data (bmp, i); + if (!buffer) + return -1; + +#if 0 + memset (buffer, 0xFF, 512); + value = 0; +#else + memset (buffer, 0x00, 512); + value = 1; +#endif + //utils_dump_mem (buffer, 0, 32, DM_DEFAULTS); + //printf ("\n"); + + begin = i & ~4095; + end = begin + 4095; + //printf ("begin = %lld, vcn = %lld,%lld end = %lld\n", begin, vcn, vcn+length-1, end); + + if ((vcn > begin) && (vcn < end)) { + //printf ("1\n"); + start = ((vcn+8) >> 3) & 511; + sta_part = 0xff << (vcn&7); + } else { + //printf ("2\n"); + start = 0; + } + + if (((vcn+length-1) >= begin) && ((vcn+length-1) <= end)) { + //printf ("3\n"); + finish = ((vcn+length-1) >> 3) & 511; + fin_part = 0xff >> (7-((vcn+length-1)&7)); + } else { + //printf ("4\n"); + finish = 511; + } + +#if 0 + //printf ("\n"); + printf ("%lld) ", i>>12); + if (start > 0) { + printf ("(%02x) ", sta_part); + } else { + printf (" "); + } + + printf ("%d - %d", start, finish); + + if (finish < 511) { + printf (" (%02x)\n", fin_part); + } else { + printf (" \n"); + } +#endif + if (value) { + if (start != 0) + buffer[start-1] |= sta_part; + if ((finish - start) > 0) + memset (buffer+start, 0xff, finish-start); + buffer[finish] |= fin_part; + } else { + if (start != 0) + buffer[start-1] &= ~sta_part; + if ((finish - start) > 0) + memset (buffer+start, 0x00, finish-start); + buffer[finish] &= ~fin_part; + } + utils_dump_mem (buffer, 0, 16, DM_DEFAULTS); + } + + return 1; +} + + /** * ntfs_dt_alloc_children */ @@ -1175,6 +1389,47 @@ static int utils_free_non_residents (ntfs_inode *inode) return 0; } +/** + * utils_free_non_residents2 + */ +static int utils_free_non_residents2 (ntfs_inode *inode, struct ntfs_bmp *bmp) +{ + ntfs_attr_search_ctx *ctx; + ntfs_attr *na; + ATTR_RECORD *arec; + + if (!inode) + return -1; + + ctx = ntfs_attr_get_search_ctx (NULL, inode->mrec); + if (!ctx) { + printf ("can't create a search context\n"); + return -1; + } + + while (ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx) == 0) { + arec = ctx->attr; + if (arec->non_resident) { + na = ntfs_attr_open (inode, arec->type, NULL, 0); + if (na) { + runlist_element *rl; + LCN size; + LCN count; + ntfs_attr_map_whole_runlist (na); + rl = na->rl; + size = na->allocated_size >> inode->vol->cluster_size_bits; + for (count = 0; count < size; count += rl->length, rl++) { + ntfs_bmp_set_range (bmp, rl->lcn, rl->length, 0); + } + ntfs_attr_close (na); + } + } + } + + ntfs_attr_put_search_ctx (ctx); + return 0; +} + /** * ntfs_mft_resize_resident @@ -2969,6 +3224,32 @@ done: return 0; } +/** + * ntfs_test_bmp + */ +static int ntfs_test_bmp (ntfs_volume *vol, ntfs_inode *inode, int s, int f) +{ + ntfs_inode *volbmp; + struct ntfs_bmp *bmp; + //u8 *buffer; + //int i; + + volbmp = ntfs_inode_open (vol, FILE_Bitmap); + if (!volbmp) + return 1; + + bmp = ntfs_bmp_alloc (volbmp, AT_DATA, NULL, 0); + if (!bmp) + return 1; + + if (0) utils_free_non_residents2 (inode, bmp); + + ntfs_bmp_set_range (bmp, s, f, 1); + + ntfs_bmp_free (bmp); + return 0; +} + /** * main - Begin here @@ -3018,6 +3299,7 @@ int main (int argc, char *argv[]) if (0) result = ntfs_ie_test(); if (0) result = ntfs_file_add (vol, opts.file); if (0) result = ntfs_file_remove (vol, opts.file); + if (0) result = ntfs_test_bmp (vol, inode, s, f-s+1); done: ntfs_inode_close (inode);