diff --git a/ntfsprogs/ntfsrm.c b/ntfsprogs/ntfsrm.c index f1f25661..526723d5 100644 --- a/ntfsprogs/ntfsrm.c +++ b/ntfsprogs/ntfsrm.c @@ -2020,51 +2020,6 @@ static int ntfs_dt_transfer (struct ntfs_dt *old, struct ntfs_dt *new, int start } -/** - * utils_free_non_residents - */ -static int utils_free_non_residents (ntfs_inode *inode) -{ - // XXX need to do this in memory - - 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++) { - //printf ("rl(%llu,%llu,%lld)\n", rl->vcn, rl->lcn, rl->length); - //printf ("freed %d\n", ntfs_cluster_free (inode->vol, na, rl->vcn, rl->length)); - ntfs_cluster_free (inode->vol, na, rl->vcn, rl->length); - } - ntfs_attr_close (na); - } - } - } - - ntfs_attr_put_search_ctx (ctx); - return 0; -} - /** * utils_free_non_residents3 */ @@ -2128,130 +2083,6 @@ static int utils_free_non_residents2 (ntfs_inode *inode, struct ntfs_bmp *bmp) } -/** - * utils_mftrec_mark_free - */ -static int utils_mftrec_mark_free (ntfs_volume *vol, MFT_REF mref) -{ - static u8 buffer[512]; - static s64 bmpmref = -sizeof (buffer) - 1; /* Which bit of $BITMAP is in the buffer */ - - int byte, bit; - - if (!vol) { - errno = EINVAL; - return -1; - } - - mref = MREF (mref); - //printf ("mref = %lld\n", mref); - /* Does mref lie in the section of $Bitmap we already have cached? */ - if (((s64)mref < bmpmref) || ((s64)mref >= (bmpmref + - (sizeof (buffer) << 3)))) { - Dprintf ("Bit lies outside cache.\n"); - - /* Mark the buffer as not in use, in case the read is shorter. */ - memset (buffer, 0, sizeof (buffer)); - bmpmref = mref & (~((sizeof (buffer) << 3) - 1)); - - if (ntfs_attr_pread (vol->mftbmp_na, (bmpmref>>3), sizeof (buffer), buffer) < 0) { - Eprintf ("Couldn't read $MFT/$BITMAP: %s\n", strerror (errno)); - return -1; - } - - Dprintf ("Reloaded bitmap buffer.\n"); - } - - bit = 1 << (mref & 7); - byte = (mref >> 3) & (sizeof (buffer) - 1); - Dprintf ("cluster = %lld, bmpmref = %lld, byte = %d, bit = %d, in use %d\n", - mref, bmpmref, byte, bit, buffer[byte] & bit); - - if ((buffer[byte] & bit) == 0) { - Eprintf ("MFT record isn't in use (1).\n"); - return -1; - } - - //utils_dump_mem (buffer, byte, 1, DM_NO_ASCII); - buffer[byte] &= ~bit; - //utils_dump_mem (buffer, byte, 1, DM_NO_ASCII); - - if (ntfs_attr_pwrite (vol->mftbmp_na, (bmpmref>>3), sizeof (buffer), buffer) < 0) { - Eprintf ("Couldn't write $MFT/$BITMAP: %s\n", strerror (errno)); - return -1; - } - - return (buffer[byte] & bit); -} - -/** - * utils_mftrec_mark_free2 - */ -static int utils_mftrec_mark_free2 (ntfs_volume *vol, MFT_REF mref) -{ - u8 buffer[1024]; - s64 res; - MFT_RECORD *rec; - - if (!vol) - return -1; - - mref = MREF (mref); - rec = (MFT_RECORD*) buffer; - - res = ntfs_mft_record_read (vol, mref, rec); - printf ("res = %lld\n", res); - - if ((rec->flags & MFT_RECORD_IN_USE) == 0) { - Eprintf ("MFT record isn't in use (2).\n"); - return -1; - } - - rec->flags &= ~MFT_RECORD_IN_USE; - - //printf ("\n"); - //utils_dump_mem (buffer, 0, 1024, DM_DEFAULTS); - - res = ntfs_mft_record_write (vol, mref, rec); - printf ("res = %lld\n", res); - - return 0; -} - -/** - * utils_mftrec_mark_free3 - */ -static int utils_mftrec_mark_free3 (struct ntfs_bmp *bmp, MFT_REF mref) -{ - return ntfs_bmp_set_range (bmp, (VCN) MREF (mref), 1, 0); -} - -/** - * utils_mftrec_mark_free4 - */ -static int utils_mftrec_mark_free4 (ntfs_inode *inode) -{ - MFT_RECORD *rec; - - if (!inode) - return -1; - - rec = (MFT_RECORD*) inode->mrec; - - if ((rec->flags & MFT_RECORD_IN_USE) == 0) { - Eprintf ("MFT record isn't in use (3).\n"); - return -1; - } - - rec->flags &= ~MFT_RECORD_IN_USE; - - //printf ("\n"); - //utils_dump_mem (buffer, 0, 1024, DM_DEFAULTS); - - printf (GREEN "Modified: inode %lld MFT_RECORD header\n" END, inode->mft_no); - return 0; -} - /** * utils_mftrec_mark_free5 */ @@ -2986,369 +2817,6 @@ static int ntfs_dt_alloc_add (struct ntfs_dt *add, INDEX_ENTRY *add_ie) return 0; } -/** - * ntfs_dt_remove_alloc - */ -static int ntfs_dt_remove_alloc (struct ntfs_dt *dt, int index_num) -{ - INDEX_ENTRY *ie = NULL; - int i; - u8 *dst; - u8 *src; - u8 *end; - int off; - int len; - s64 res; - - //printf ("removing entry %d of %d\n", index_num+1, dt->child_count); - //printf ("index size = %d\n", dt->data_len); - //printf ("index use = %d\n", dt->header->index_length); - - //utils_dump_mem (dt->data, 0, dt->data_len, DM_DEFAULTS); - - off = (u8*)dt->children[0] - dt->data; - for (i = 0; i < dt->child_count; i++) { - ie = dt->children[i]; - - //printf ("%2d %4d ", i, off); - off += ie->length; - - if (ie->flags & INDEX_ENTRY_END) { - //printf ("END (%d)\n", ie->length); - break; - } - - //ntfs_name_print (ie->key.file_name.file_name, ie->key.file_name.file_name_length); - //printf (" (%d)\n", ie->length); - } - //printf ("total = %d\n", off); - - ie = dt->children[index_num]; - dst = (u8*)ie; - - src = dst + ie->length; - - ie = dt->children[dt->child_count-1]; - end = (u8*)ie + ie->length; - - len = end - src; - - //printf ("move %d bytes\n", len); - //printf ("%d, %d, %d\n", dst - dt->data, src - dt->data, len); - memmove (dst, src, len); - - //printf ("clear %d bytes\n", dt->data_len - (dst - dt->data) - len); - //printf ("%d, %d, %d\n", dst - dt->data + len, 0, dt->data_len - (dst - dt->data) - len); - - //ntfs_dt_print (dt->dir->index, 0); - - memset (dst + len, 0, dt->data_len - (dst - dt->data) - len); - - for (i = 0; i < dt->child_count; i++) { - if (dt->sub_nodes[i]) { - printf ("this shouldn't happen %p\n", dt->sub_nodes[i]); - ntfs_dt_free (dt->sub_nodes[i]); // shouldn't be any, yet - } - } - - free (dt->sub_nodes); - dt->sub_nodes = NULL; - free (dt->children); - dt->children = NULL; - dt->child_count = 0; - - //printf ("before = %d\n", dt->header->index_length + 24); - dt->header->index_length -= src - dst; - //printf ("after = %d\n", dt->header->index_length + 24); - - ntfs_dt_count_alloc (dt); - - //utils_dump_mem (dt->data, 0, dt->data_len, DM_DEFAULTS); - -#if 0 - //printf ("\n"); - //printf ("index size = %d\n", dt->data_len); - //printf ("index use = %d\n", dt->header.index_length); - - off = (u8*)dt->children[0] - dt->data; - for (i = 0; i < dt->child_count; i++) { - ie = dt->children[i]; - - printf ("%2d %4d ", i, off); - off += ie->length; - - if (ie->flags & INDEX_ENTRY_END) { - printf ("END (%d)\n", ie->length); - break; - } - - ntfs_name_print (ie->key.file_name.file_name, - ie->key.file_name.file_name_length); - printf (" (%d)\n", ie->length); - } -#endif - //utils_dump_mem (dt->data, 0, dt->data_len, DM_DEFAULTS); - res = ntfs_attr_mst_pwrite (dt->dir->ialloc, dt->vcn*512, 1, dt->data_len, dt->data); - printf ("res = %lld\n", res); - - return 0; -} - -/** - * ntfs_dt_remove_root - */ -static int ntfs_dt_remove_root (struct ntfs_dt *dt, int index_num) -{ - INDEX_ENTRY *ie = NULL; - INDEX_ROOT *ir = NULL; - int i; - u8 *dst; - u8 *src; - u8 *end; - int off; - int len; - s64 res; - - //printf ("removing entry %d of %d\n", index_num+1, dt->child_count); - //printf ("index size = %d\n", dt->data_len); - //printf ("index use = %d\n", dt->header->index_length); - - //utils_dump_mem (dt->data, 0, dt->data_len, DM_DEFAULTS); - - off = (u8*)dt->children[0] - dt->data; - for (i = 0; i < dt->child_count; i++) { - ie = dt->children[i]; - - //printf ("%2d %4d ", i+1, off); - off += ie->length; - - if (ie->flags & INDEX_ENTRY_END) { - //printf ("END (%d)\n", ie->length); - break; - } - - //ntfs_name_print (ie->key.file_name.file_name, ie->key.file_name.file_name_length); - //printf (" (%d)\n", ie->length); - } - //printf ("total = %d\n", off); - - ie = dt->children[index_num]; - dst = (u8*)ie; - - src = dst + ie->length; - - ie = dt->children[dt->child_count-1]; - end = (u8*)ie + ie->length; - - len = end - src; - - //printf ("move %d bytes\n", len); - //printf ("%d, %d, %d\n", dst - dt->data, src - dt->data, len); - memmove (dst, src, len); - - dt->data_len -= (src - dt->data - sizeof (INDEX_ROOT)); - dt->child_count--; - - ir = (INDEX_ROOT*) dt->data; - ir->index.index_length = dt->data_len - 16; - ir->index.allocated_size = dt->data_len - 16; - - ntfs_mft_resize_resident (dt->dir->inode, AT_INDEX_ROOT, I30, 4, dt->data, dt->data_len); - dt->data = realloc (dt->data, dt->data_len); - - //printf ("ih->index_length = %d\n", ir->index.index_length); - //printf ("ih->allocated_size = %d\n", ir->index.allocated_size); - //printf ("dt->data_len = %d\n", dt->data_len); - - //utils_dump_mem (dt->data, 0, dt->data_len, DM_DEFAULTS); - //ntfs_dt_print (dt->dir->index, 0); -#if 1 - for (i = 0; i < dt->child_count; i++) { - if (dt->sub_nodes[i]) { - printf ("this shouldn't happen %p\n", dt->sub_nodes[i]); - ntfs_dt_free (dt->sub_nodes[i]); // shouldn't be any, yet - } - } - - free (dt->sub_nodes); - dt->sub_nodes = NULL; - free (dt->children); - dt->children = NULL; - dt->child_count = 0; - - //printf ("before = %d\n", dt->header->index_length + 24); - dt->header->index_length -= src - dst; - //printf ("after = %d\n", dt->header->index_length + 24); - - ntfs_dt_count_root (dt); -#endif - //utils_dump_mem (dt->data, 0, dt->data_len, DM_DEFAULTS); - -#if 0 - //printf ("\n"); - //printf ("index size = %d\n", dt->data_len); - //printf ("index use = %d\n", dt->header.index_length); - - off = (u8*)dt->children[0] - dt->data; - for (i = 0; i < dt->child_count; i++) { - ie = dt->children[i]; - - printf ("%2d %4d ", i, off); - off += ie->length; - - if (ie->flags & INDEX_ENTRY_END) { - printf ("END (%d)\n", ie->length); - break; - } - - ntfs_name_print (ie->key.file_name.file_name, - ie->key.file_name.file_name_length); - printf (" (%d)\n", ie->length); - } -#endif - //utils_dump_mem (dt->data, 0, dt->data_len, DM_DEFAULTS); - - res = ntfs_mft_record_write (dt->dir->inode->vol, dt->dir->inode->mft_no, dt->dir->inode->mrec); - printf ("res = %lld\n", res); - - return 0; -} - -/** - * ntfs_dt_remove - */ -static int ntfs_dt_remove (struct ntfs_dt *dt, int index_num) -{ - if (!dt) - return 1; - if ((index_num < 0) || (index_num >= dt->child_count)) - return 1; - - if (ntfs_dt_root (dt)) - return ntfs_dt_remove_root (dt, index_num); - else - return ntfs_dt_remove_alloc (dt, index_num); -} - -/** - * ntfs_dt_del_child - */ -static int ntfs_dt_del_child (struct ntfs_dt *dt, ntfschar *uname, int len) -{ - struct ntfs_dt *del; - INDEX_ENTRY *ie; - ntfs_inode *ichild = NULL; - ntfs_inode *iparent = NULL; - ntfs_attr *attr = NULL; - ntfs_attr_search_ctx *ctx = NULL; - int index_num = 0; - int res = 1; - ATTR_RECORD *arec = NULL; - MFT_REF mft_num = -1; - FILE_NAME_ATTR *file; - int filenames = 0; - - // compressed & encrypted files? - - del = ntfs_dt_find2 (dt, uname, len, &index_num); - if (!del) { - printf ("can't find item to delete\n"); - goto close; - } - - if ((index_num < 0) || (index_num >= del->child_count)) { - printf ("error in dt_find\n"); - goto close; - } - - if (del->header->flags & INDEX_NODE) { - printf ("can only delete leaf nodes\n"); - goto close; - } - - /* - if (!del->parent) { - printf ("has 0xA0, but isn't in use\n"); - goto close; - } - */ - - ie = del->children[index_num]; - if (ie->key.file_name.file_attributes & FILE_ATTR_DIRECTORY) { - printf ("can't delete directories\n"); - goto close; - } - - if (ie->key.file_name.file_attributes & FILE_ATTR_SYSTEM) { - printf ("can't delete system files\n"); - goto close; - } - - ichild = ntfs_inode_open2 (dt->dir->vol, MREF (ie->indexed_file)); - if (!ichild) { - printf ("can't open inode\n"); - goto close; - } - - ctx = ntfs_attr_get_search_ctx (NULL, ichild->mrec); - if (!ctx) { - printf ("can't create a search context\n"); - goto close; - } - - while (ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx) == 0) { - arec = ctx->attr; - if (arec->type == AT_ATTRIBUTE_LIST) { - printf ("can't delete files with an attribute list\n"); - goto close; - } - if (arec->type == AT_INDEX_ROOT) { - printf ("can't delete directories\n"); - goto close; - } - if (arec->type == AT_FILE_NAME) { - filenames++; - file = (FILE_NAME_ATTR*) ((u8*) arec + arec->value_offset); - mft_num = MREF (file->parent_directory); - } - } - - if (filenames != 1) { - printf ("file has more than one name\n"); - goto close; - } - - iparent = ntfs_inode_open2 (dt->dir->vol, mft_num); - if (!iparent) { - printf ("can't open parent directory\n"); - goto close; - } - - /* - attr = ntfs_attr_open (iparent, AT_INDEX_ALLOCATION, I30, 4); - if (!attr) { - printf ("parent doesn't have 0xA0\n"); - goto close; - } - */ - - //printf ("deleting file\n"); - //ntfs_dt_print (del->dir->index, 0); - - if (1) res = utils_free_non_residents (ichild); - if (1) res = utils_mftrec_mark_free (dt->dir->vol, del->children[index_num]->indexed_file); - if (1) res = utils_mftrec_mark_free2 (dt->dir->vol, del->children[index_num]->indexed_file); - if (1) res = ntfs_dt_remove (del, index_num); - -close: - ntfs_attr_put_search_ctx (ctx); - ntfs_attr_close (attr); - ntfs_inode_close2 (iparent); - ntfs_inode_close2 (ichild); - - return res; -} - /** * ntfs_dt_add_alloc */ @@ -4501,47 +3969,6 @@ close: } -/** - * ntfsrm - */ -static int ntfsrm (ntfs_volume *vol, char *name) -{ - struct ntfs_dir *dir = NULL; - struct ntfs_dir *finddir = NULL; - MFT_REF mft_num; - ntfschar *uname = NULL; - int len; - - dir = ntfs_dir_alloc (vol, FILE_root); - if (!dir) - return 1; - - //mft_num = ntfs_dir_find (dir, name); - //printf ("%s = %lld\n", name, mft_num); - - mft_num = utils_pathname_to_mftref (vol, dir, name, &finddir); - //printf ("mft_num = %lld\n", mft_num); - //ntfs_dir_print (finddir, 0); - - if (!finddir) { - printf ("Couldn't find the index entry for %s\n", name); - return 1; - } - - if (rindex (name, PATH_SEP)) - name = rindex (name, PATH_SEP) + 1; - - len = ntfs_mbstoucs (name, &uname, 0); - if (len < 0) - return 1; - - ntfs_dt_del_child (finddir->index, uname, len); - - ntfs_dir_free (dir); - free (uname); - return 0; -} - /** * ntfs_index_dump_alloc */ @@ -4607,6 +4034,11 @@ static int ntfs_index_dump (ntfs_inode *inode) return 0; iroot = ntfs_attr_open (inode, AT_INDEX_ROOT, I30, 4); + if (!iroot) { + printf ("not a directory\n"); + return 0; + } + ialloc = ntfs_attr_open (inode, AT_INDEX_ALLOCATION, I30, 4); size = (int) ntfs_attr_pread (iroot, 0, sizeof (buffer), buffer); @@ -5045,38 +4477,6 @@ static int ntfs_file_remove2 (ntfs_volume *vol, struct ntfs_dt *dt, int dt_num) return 0; } -/** - * ntfs_test_bmp - */ -static int ntfs_test_bmp (ntfs_volume *vol, ntfs_inode *inode) -{ - ntfs_inode *volbmp; - struct ntfs_bmp *bmp; - struct ntfs_bmp *bmp2; - //u8 *buffer; - //int i; - - volbmp = ntfs_inode_open2 (vol, FILE_Bitmap); - if (!volbmp) - return 1; - - bmp = ntfs_bmp_alloc (volbmp, AT_DATA, NULL, 0); - if (!bmp) - return 1; - - bmp2 = ntfs_bmp_alloc (vol->mft_ni, AT_BITMAP, NULL, 0); - if (!bmp2) - return 1; - - if (0) ntfs_bmp_set_range (bmp, 0, 9, 1); - if (0) utils_free_non_residents2 (inode, bmp); - if (0) utils_mftrec_mark_free3 (bmp2, inode->mft_no); - if (0) utils_mftrec_mark_free4 (inode); - - ntfs_bmp_free (bmp); - return 0; -} - /** * ntfs_test_bmp2 */ @@ -5190,12 +4590,10 @@ int main (int argc, char *argv[]) //printf ("inode = %lld\n", inode->mft_no); - if (0) result = ntfs_index_dump (inode); - if (0) result = ntfsrm (vol, opts.file); + if (1) result = ntfs_index_dump (inode); if (0) result = ntfs_ie_test(); if (0) result = ntfs_file_add (vol, opts.file); - if (1) result = ntfs_file_remove2 (vol, find.dt, find.dt_index); - if (0) result = ntfs_test_bmp (vol, inode); + if (0) result = ntfs_file_remove2 (vol, find.dt, find.dt_index); if (0) result = ntfs_test_bmp2 (vol); done: