prepare to Szaka's code merge: remove not working Rich's index code

edge.strict_endians
yura 2006-07-17 11:49:52 +00:00
parent 2d137b6900
commit 28a2b1f2b0
18 changed files with 0 additions and 2190 deletions

View File

@ -149,15 +149,6 @@ AC_ARG_ENABLE(debug-logging,
fi,
)
AC_ARG_ENABLE(rich,
AS_HELP_STRING(--enable-rich,enable Rich's "rm" test code), ,
enable_rich=no
)
AM_CONDITIONAL(ENABLE_RICH, test "$enable_rich" = yes)
if test "$enable_rich" = "yes"; then
CFLAGS="$CFLAGS -DNTFS_RICH"
fi
# Use GNU extensions if available.
AC_GNU_SOURCE

View File

@ -25,11 +25,9 @@ linux_ntfsinclude_HEADERS = \
mft.h \
mst.h \
ntfstime.h \
rich.h \
runlist.h \
security.h \
support.h \
tree.h \
types.h \
unistr.h \
version.h \

View File

@ -131,37 +131,4 @@ static __inline__ int ntfs_bitmap_clear_bit(ntfs_attr *na, s64 bit)
return ntfs_bitmap_clear_run(na, bit, 1);
}
#ifdef NTFS_RICH
#include "layout.h"
#include "inode.h"
/**
* struct ntfs_bmp -
*
* a cache for either dir/$BITMAP, $MFT/$BITMAP or $Bitmap/$DATA
*/
struct ntfs_bmp {
ntfs_volume *vol;
ntfs_attr *attr;
int count;
u8 **data;
VCN *data_vcn;
};
int ntfs_bmp_rollback(struct ntfs_bmp *bmp);
int ntfs_bmp_commit(struct ntfs_bmp *bmp);
void ntfs_bmp_free(struct ntfs_bmp *bmp);
struct ntfs_bmp * ntfs_bmp_create(ntfs_inode *inode, ATTR_TYPES type, ntfschar *name, int name_len);
int ntfs_bmp_add_data(struct ntfs_bmp *bmp, VCN vcn, u8 *data);
u8 * ntfs_bmp_get_data(struct ntfs_bmp *bmp, VCN vcn);
int ntfs_bmp_set_range(struct ntfs_bmp *bmp, VCN vcn, s64 length, int value);
s64 ntfs_bmp_find_last_set(struct ntfs_bmp *bmp);
int ntfs_bmp_find_space(struct ntfs_bmp *bmp, LCN start, long size);
#endif /* NTFS_RICH */
#endif /* defined _NTFS_BITMAP_H */

View File

@ -107,37 +107,4 @@ typedef int (*ntfs_filldir_t)(void *dirent, const ntfschar *name,
extern int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos,
void *dirent, ntfs_filldir_t filldir);
#ifdef NTFS_RICH
/**
* struct ntfs_dir -
*/
struct ntfs_dir {
ntfs_volume *vol;
struct ntfs_dir *parent;
ntfschar *name;
int name_len;
MFT_REF mft_num;
struct ntfs_dt *index;
struct ntfs_dir **children;
int child_count;
struct ntfs_bmp *bitmap;
ntfs_inode *inode;
ntfs_attr *iroot;
ntfs_attr *ialloc;
int index_size;
};
int ntfs_dir_rollback(struct ntfs_dir *dir);
int ntfs_dir_truncate(ntfs_volume *vol, struct ntfs_dir *dir);
int ntfs_dir_commit(struct ntfs_dir *dir);
void ntfs_dir_free(struct ntfs_dir *dir);
struct ntfs_dir * ntfs_dir_create(ntfs_volume *vol, MFT_REF mft_num);
void ntfs_dir_add(struct ntfs_dir *parent, struct ntfs_dir *child);
struct ntfs_dir * ntfs_dir_find2(struct ntfs_dir *dir, ntfschar *name, int name_len);
#endif /* NTFS_RICH */
#endif /* defined _NTFS_DIR_H */

View File

@ -129,21 +129,4 @@ static inline void ntfs_index_entry_mark_dirty(ntfs_index_context *ictx)
ictx->ia_dirty = TRUE;
}
#ifdef NTFS_RICH
#include "layout.h"
void ntfs_ie_free(INDEX_ENTRY *ie);
INDEX_ENTRY * ntfs_ie_create(void);
VCN ntfs_ie_get_vcn(INDEX_ENTRY *ie);
INDEX_ENTRY * ntfs_ie_copy(INDEX_ENTRY *ie);
INDEX_ENTRY * ntfs_ie_set_vcn(INDEX_ENTRY *ie, VCN vcn);
INDEX_ENTRY * ntfs_ie_remove_vcn(INDEX_ENTRY *ie);
INDEX_ENTRY * ntfs_ie_set_name(INDEX_ENTRY *ie, ntfschar *name, int namelen, FILE_NAME_TYPE_FLAGS nametype);
INDEX_ENTRY * ntfs_ie_remove_name(INDEX_ENTRY *ie);
#endif /* NTFS_RICH */
#endif /* _NTFS_INDEX_H */

View File

@ -187,12 +187,4 @@ extern int ntfs_inode_free_space(ntfs_inode *ni, int size);
extern int ntfs_inode_badclus_bad(u64 mft_no, ATTR_RECORD *a);
#ifdef NTFS_RICH
int ntfs_inode_close2(ntfs_inode *ni);
ntfs_inode * ntfs_inode_open2(ntfs_volume *vol, const MFT_REF mref);
ntfs_inode * ntfs_inode_open3(ntfs_volume *vol, const MFT_REF mref);
#endif /* NTFS_RICH */
#endif /* defined _NTFS_INODE_H */

View File

@ -113,18 +113,4 @@ extern int ntfs_mft_record_free(ntfs_volume *vol, ntfs_inode *ni);
extern int ntfs_mft_usn_dec(MFT_RECORD *mrec);
#ifdef NTFS_RICH
#include "bitmap.h"
#include "dir.h"
int ntfs_mft_remove_attr(struct ntfs_bmp *bmp, ntfs_inode *inode, ATTR_TYPES type);
ATTR_RECORD * ntfs_mft_add_attr(ntfs_inode *inode, ATTR_TYPES type, u8 *data, int data_len);
int ntfs_mft_resize_resident(ntfs_inode *inode, ATTR_TYPES type, ntfschar *name, int name_len, u8 *data, int data_len);
int ntfs_mft_free_space(struct ntfs_dir *dir);
int ntfs_mft_add_index(struct ntfs_dir *dir);
#endif /* NTFS_RICH */
#endif /* defined _NTFS_MFT_H */

View File

@ -228,16 +228,4 @@ extern int ntfs_logfile_reset(ntfs_volume *vol);
extern int ntfs_volume_write_flags(ntfs_volume *vol, const u16 flags);
#ifdef NTFS_RICH
int ntfs_volume_commit(ntfs_volume *vol);
int ntfs_volume_rollback(ntfs_volume *vol);
int ntfs_volume_umount2(ntfs_volume *vol, const BOOL force);
ntfs_volume * ntfs_volume_mount2(const char *device, unsigned long flags, BOOL force);
int utils_valid_device(const char *name, int force);
ntfs_volume * utils_mount_volume(const char *device, unsigned long flags, BOOL force);
#endif /* NTFS_RICH */
#endif /* defined _NTFS_VOLUME_H */

View File

@ -60,10 +60,6 @@ libntfs_la_SOURCES = \
version.c \
volume.c
if ENABLE_RICH
libntfs_la_SOURCES += rich.c tree.c
endif
if ENABLE_GNOME_VFS
gnomevfsmoduleslibdir = $(libdir)/gnome-vfs-2.0/modules

View File

@ -230,445 +230,3 @@ int ntfs_bitmap_clear_run(ntfs_attr *na, s64 start_bit, s64 count)
return ntfs_bitmap_set_bits_in_run(na, start_bit, count, 0);
}
#ifdef NTFS_RICH
#include "layout.h"
#include "volume.h"
#include "rich.h"
/**
* ntfs_bmp_rollback - Discard the in-memory bitmap changes
* @bmp:
*
* Description...
*
* Returns:
*/
int ntfs_bmp_rollback(struct ntfs_bmp *bmp)
{
int i;
if ((!bmp) || (bmp->count == 0))
return 0;
ntfs_log_trace ("bmp %p, records %d, attr %lld/%02X\n", bmp, bmp->count, MREF(bmp->attr->ni->mft_no), bmp->attr->type);
for (i = 0; i < bmp->count; i++)
free(bmp->data[i]);
free(bmp->data);
free(bmp->data_vcn);
bmp->data = NULL;
bmp->data_vcn = NULL;
bmp->count = 0;
return 0;
}
/**
* ntfs_bmp_commit - Write the cached bitmap data to disk
* @bmp:
*
* Description...
*
* Returns:
*/
int ntfs_bmp_commit(struct ntfs_bmp *bmp)
{
int i;
u32 cs;
u32 ws; // write size
if (!bmp)
return 0;
if (bmp->count == 0)
return 0;
ntfs_log_trace ("bmp %p, records %d, attr %lld/%02X\n", bmp, bmp->count, MREF(bmp->attr->ni->mft_no), bmp->attr->type);
#if 0
ntfs_log_debug("attr = 0x%02X\n", bmp->attr->type);
ntfs_log_debug("resident = %d\n", !NAttrNonResident(bmp->attr));
ntfs_log_debug("\ta size = %lld\n", bmp->attr->allocated_size);
ntfs_log_debug("\td size = %lld\n", bmp->attr->data_size);
ntfs_log_debug("\ti size = %lld\n", bmp->attr->initialized_size);
#endif
ntfs_log_debug("commit bmp inode %lld, 0x%02X (%sresident)\n", bmp->attr->ni->mft_no, bmp->attr->type, NAttrNonResident(bmp->attr) ? "non-" : "");
if (NAttrNonResident(bmp->attr)) {
cs = bmp->vol->cluster_size;
// non-resident
for (i = 0; i < bmp->count; i++) {
if (((bmp->data_vcn[i]+1) * cs) < bmp->attr->data_size)
ws = cs;
else
ws = bmp->attr->data_size & (cs - 1);
//ntfs_log_debug("writing %d bytes\n", ws);
ntfs_attr_pwrite(bmp->attr, bmp->data_vcn[i] * cs, ws, bmp->data[i]); // XXX retval
ntfs_log_warning("\tntfs_attr_pwrite(vcn %lld)\n", bmp->data_vcn[i]);
}
} else {
// resident
ntfs_attr_pwrite(bmp->attr, bmp->data_vcn[0], bmp->attr->data_size, bmp->data[0]); // XXX retval
ntfs_log_warning("\tntfs_attr_pwrite resident (%lld)\n", bmp->attr->data_size);
}
ntfs_bmp_rollback(bmp);
return 0;
}
/**
* ntfs_bmp_free - Destroy a bitmap object
* @bmp:
*
* Description...
*
* Returns:
*/
void ntfs_bmp_free(struct ntfs_bmp *bmp)
{
if (!bmp)
return;
ntfs_log_trace ("bmp %p, records %d, attr %lld/%02X\n", bmp, bmp->count, MREF(bmp->attr->ni->mft_no), bmp->attr->type);
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, 4);
bmp->count++;
new = ROUND_UP(bmp->count, 4);
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, bmp->vol->cluster_size_bits + 3);
b = ROUND_DOWN(vcn_finish, bmp->vol->cluster_size_bits + 3) + 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_bits) >> 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 */

View File

@ -1756,443 +1756,3 @@ err_out:
return -1;
}
#ifdef NTFS_RICH
#include "layout.h"
#include "tree.h"
#include "bitmap.h"
#include "rich.h"
/**
* ntfs_dir_rollback - Discard the in-memory directory changes
* @dir:
*
* Description...
*
* Returns:
*/
int ntfs_dir_rollback(struct ntfs_dir *dir)
{
int i;
if (!dir)
return -1;
ntfs_log_trace ("dir %p, inode %lld, children %d\n", dir,
dir ? MREF(dir->mft_num) : 0, dir ? dir->child_count : 0);
if (ntfs_dt_rollback(dir->index) < 0)
return -1;
if (ntfs_bmp_rollback(dir->bitmap) < 0)
return -1;
for (i = 0; i < dir->child_count; i++) {
if (ntfs_dir_rollback(dir->children[i]) < 0)
return -1;
}
return 0;
}
/**
* ntfs_dir_truncate - Shrink an index allocation
* @vol:
* @dir:
*
* Description...
*
* Returns:
*/
int ntfs_dir_truncate(ntfs_volume *vol, struct ntfs_dir *dir)
{
//int i;
//u8 *buffer;
//int buf_count;
s64 last_bit;
INDEX_ENTRY *ie;
if (!vol || !dir)
return -1;
ntfs_log_trace ("dir %p, inode %lld, children %d\n", dir,
dir ? MREF(dir->mft_num) : 0, dir ? dir->child_count : 0);
if ((dir->ialloc == NULL) || (dir->bitmap == NULL))
return 0;
#if 0
buf_count = ROUND_UP(dir->bitmap->attr->allocated_size, vol->cluster_size_bits) >> vol->cluster_size_bits;
ntfs_log_debug("alloc = %lld bytes\n", dir->ialloc->allocated_size);
ntfs_log_debug("alloc = %lld clusters\n", dir->ialloc->allocated_size >> vol->cluster_size_bits);
ntfs_log_debug("bitmap bytes 0 to %lld\n", ((dir->ialloc->allocated_size >> vol->cluster_size_bits)-1)>>3);
ntfs_log_debug("bitmap = %p\n", dir->bitmap);
ntfs_log_debug("bitmap = %lld bytes\n", dir->bitmap->attr->allocated_size);
ntfs_log_debug("bitmap = %d buffers\n", buf_count);
#endif
last_bit = ntfs_bmp_find_last_set(dir->bitmap);
if (dir->ialloc->allocated_size == (dir->index_size * (last_bit + 1))) {
//ntfs_log_debug("nothing to do\n");
return 0;
}
ntfs_log_debug("Truncation needed\n");
#if 0
ntfs_log_debug("\tlast bit = %lld\n", last_bit);
ntfs_log_debug("\tactual IALLOC size = %lld\n", dir->ialloc->allocated_size);
ntfs_log_debug("\tshould IALLOC size = %lld\n", dir->index_size * (last_bit + 1));
#endif
if ((dir->index_size * (last_bit + 1)) == 0) {
ntfs_log_debug("root dt %d, vcn = %lld\n", dir->index->changed, dir->index->vcn);
//rollback all dts
//ntfs_dt_rollback(dir->index);
//dir->index = NULL;
// What about the ROOT dt?
ie = ntfs_ie_copy(dir->index->children[0]);
if (!ie) {
ntfs_log_warning("IE copy failed\n");
return -1;
}
ie = ntfs_ie_remove_vcn(ie);
if (!ie) {
ntfs_log_warning("IE remove vcn failed\n");
return -1;
}
//utils_dump_mem(dir->index->data, 0, dir->index->data_len, DM_DEFAULTS); ntfs_log_debug("\n");
//utils_dump_mem(ie, 0, ie->length, DM_DEFAULTS); ntfs_log_debug("\n");
ntfs_dt_root_replace(dir->index, 0, dir->index->children[0], ie);
//utils_dump_mem(dir->index->data, 0, dir->index->data_len, DM_DEFAULTS); ntfs_log_debug("\n");
//ntfs_log_debug("root dt %d, vcn = %lld\n", dir->index->changed, dir->index->vcn);
ntfs_ie_free(ie);
ie = NULL;
//index flags remove LARGE_INDEX
dir->index->header->flags = 0;
//rollback dir's bmp
ntfs_bmp_free(dir->bitmap);
dir->bitmap = NULL;
/*
for (i = 0; i < dir->index->child_count; i++) {
ntfs_dt_rollback(dir->index->sub_nodes[i]);
dir->index->sub_nodes[i] = NULL;
}
*/
//ntfs_log_debug("dir->index->inodes[0] = %p\n", dir->index->inodes[0]);
//remove 0xA0 attribute
ntfs_mft_remove_attr(vol->private_bmp2, dir->inode, AT_INDEX_ALLOCATION);
//remove 0xB0 attribute
ntfs_mft_remove_attr(vol->private_bmp2, dir->inode, AT_BITMAP);
} else {
ntfs_log_warning("Cannot shrink directory\n");
//ntfs_dir_shrink_alloc
//ntfs_dir_shrink_bitmap
//make bitmap resident?
}
/*
* Remove
* dt -> dead
* bitmap updated
* rollback dead dts
* commit bitmap
* commit dts
* commit dir
*/
/*
* Reuse
* search for lowest dead
* update bitmap
* init dt
* remove from dead
* insert into tree
* init INDX
*/
#if 0
buffer = ntfs_bmp_get_data(dir->bitmap, 0);
if (!buffer)
return -1;
utils_dump_mem(buffer, 0, 8, DM_NO_ASCII);
for (i = buf_count-1; i >= 0; i--) {
if (buffer[i]) {
ntfs_log_debug("alloc in use\n");
return 0;
}
}
#endif
// <dir>/$BITMAP($I30)
// <dir>/$INDEX_ALLOCATION($I30)
// $Bitmap
// Find the highest set bit in the directory bitmap
// can we free any clusters of the alloc?
// if yes, resize attribute
// Are *any* bits set?
// If not remove ialloc
return 0;
}
/**
* ntfs_dir_commit - Write to disk the in-memory directory changes
* @dir:
*
* Description...
*
* Returns:
*/
int ntfs_dir_commit(struct ntfs_dir *dir)
{
int i;
if (!dir)
return 0;
ntfs_log_trace ("dir %p, inode %lld, children %d\n", dir,
dir ? MREF(dir->mft_num) : 0, dir ? dir->child_count : 0);
if (NInoDirty(dir->inode)) {
ntfs_inode_sync(dir->inode);
ntfs_log_warning("\tntfs_inode_sync %llu\n", dir->inode->mft_no);
}
if (ntfs_dt_commit(dir->index) < 0)
return -1;
if (ntfs_bmp_commit(dir->bitmap) < 0)
return -1;
for (i = 0; i < dir->child_count; i++) {
if (ntfs_dir_commit(dir->children[i]) < 0)
return -1;
}
return 0;
}
/**
* ntfs_dir_free - Destroy a directory object
* @dir:
*
* Description...
*
* Returns:
*/
void ntfs_dir_free(struct ntfs_dir *dir)
{
struct ntfs_dir *parent;
int i;
if (!dir)
return;
ntfs_log_trace ("dir %p, inode %lld, children %d\n", dir,
dir ? MREF(dir->mft_num) : 0, dir ? dir->child_count : 0);
ntfs_dir_rollback(dir);
parent = dir->parent;
if (parent) {
for (i = 0; i < parent->child_count; i++) {
if (parent->children[i] == dir) {
parent->children[i] = NULL;
}
}
}
ntfs_attr_close(dir->iroot);
ntfs_attr_close(dir->ialloc);
ntfs_inode_close2(dir->inode);
ntfs_dt_free (dir->index);
ntfs_bmp_free(dir->bitmap);
for (i = 0; i < dir->child_count; i++)
ntfs_dir_free(dir->children[i]);
free(dir->name);
free(dir->children);
free(dir);
}
/**
* ntfs_dir_create - Create a representation of a directory
* @vol:
* @mft_num:
*
* Description...
*
* Returns:
*/
struct ntfs_dir * ntfs_dir_create(ntfs_volume *vol, MFT_REF mft_num)
{
struct ntfs_dir *dir = NULL;
ntfs_inode *inode = NULL;
ATTR_RECORD *rec = NULL;
INDEX_ROOT *ir = NULL;
FILE_NAME_ATTR *name = NULL;
if (!vol)
return NULL;
ntfs_log_trace ("inode %lld\n", MREF(mft_num));
inode = ntfs_inode_open2(vol, mft_num);
if (!inode)
return NULL;
dir = calloc(1, sizeof(*dir));
if (!dir) {
ntfs_inode_close2(inode);
return NULL;
}
dir->inode = inode;
dir->iroot = ntfs_attr_open(inode, AT_INDEX_ROOT, NTFS_INDEX_I30, 4);
dir->ialloc = ntfs_attr_open(inode, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
if (!dir->iroot) {
ntfs_dir_free(dir);
return NULL;
}
dir->vol = vol;
dir->parent = NULL;
dir->name = NULL;
dir->name_len = 0;
dir->index = NULL;
dir->children = NULL;
dir->child_count = 0;
dir->mft_num = mft_num;
// This may not exist
dir->bitmap = ntfs_bmp_create(inode, AT_BITMAP, NTFS_INDEX_I30, 4);
if (dir->iroot) {
rec = find_first_attribute(AT_INDEX_ROOT, inode->mrec);
ir = (INDEX_ROOT*) ((u8*)rec + rec->value_offset);
dir->index_size = ir->index_block_size;
ntfs_log_debug("dir size = %d\n", dir->index_size);
} else {
// XXX !iroot?
dir->index_size = 0;
}
// Finally, find the dir's name
rec = find_first_attribute(AT_FILE_NAME, inode->mrec);
name = (FILE_NAME_ATTR*) ((u8*)rec + rec->value_offset);
dir->name_len = name->file_name_length;
dir->name = malloc(sizeof(ntfschar) * dir->name_len);
memcpy(dir->name, name->file_name, sizeof(ntfschar) * dir->name_len);
return dir;
}
/**
* ntfs_dir_add - Add a directory to another as a child
* @parent:
* @child:
*
* Description...
*
* Returns:
*/
void ntfs_dir_add(struct ntfs_dir *parent, struct ntfs_dir *child)
{
if (!parent || !child)
return;
ntfs_log_trace ("parent %p, inode %lld, children %d\n", parent,
parent ? MREF(parent->mft_num) : 0, parent ? parent->child_count : 0);
ntfs_log_trace ("child %p, inode %lld, children %d\n", child,
child ? MREF(child->mft_num) : 0, child ? child->child_count : 0);
parent->child_count++;
//ntfs_log_debug("child count = %d\n", parent->child_count);
parent->children = realloc(parent->children, parent->child_count * sizeof(struct ntfs_dir*));
child->parent = parent;
parent->children[parent->child_count-1] = child;
}
/**
* ntfs_dir_find2 - Find a directory by name
* @dir:
* @name:
* @name_len:
*
* Description...
*
* Returns:
*/
struct ntfs_dir * ntfs_dir_find2(struct ntfs_dir *dir, ntfschar *name, int name_len)
{
int i;
struct ntfs_dir *child = NULL;
struct ntfs_dt *dt = NULL;
int dt_num = 0;
INDEX_ENTRY *ie;
MFT_REF mft_num;
if (!dir || !name)
return NULL;
ntfs_log_trace ("dir %p, inode %lld, children %d\n", dir,
dir ? MREF(dir->mft_num) : 0, dir ? dir->child_count : 0);
if (!dir->index) { // XXX when will this happen?
ntfs_log_debug("ntfs_dir_find2 - directory has no index\n");
return NULL;
}
for (i = 0; i < dir->child_count; i++) {
if (0 == ntfs_names_collate(name, name_len,
dir->children[i]->name,
dir->children[i]->name_len,
2, IGNORE_CASE,
dir->vol->upcase,
dir->vol->upcase_len))
return dir->children[i];
}
dt = ntfs_dt_find2(dir->index, name, name_len, &dt_num);
if (!dt) {
ntfs_log_debug("can't find name in dir\n");
return NULL;
}
ie = dt->children[dt_num];
mft_num = ie->indexed_file;
child = ntfs_dir_create(dir->vol, mft_num);
if (!child)
return NULL;
child->index = ntfs_dt_create(child, NULL, -1);
ntfs_dir_add(dir, child);
return child;
}
#endif /* NTFS_RICH */

View File

@ -660,280 +660,6 @@ err_out:
return -1;
}
#ifdef NTFS_RICH
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include "rich.h"
/**
* ntfs_ie_free - Destroy an index entry object
* @ie:
*
* Description...
*
* Returns:
*/
void ntfs_ie_free(INDEX_ENTRY *ie)
{
ntfs_log_trace ("ie %p, inode %lld\n", ie, MREF(ie->indexed_file));
free(ie);
}
/**
* ntfs_ie_create - Create a representation of an directory index entry
*
* Description...
*
* Returns:
*/
INDEX_ENTRY * ntfs_ie_create(void)
{
int length;
INDEX_ENTRY *ie;
ntfs_log_trace ("\n");
length = 16;
ie = calloc(1, length);
if (!ie)
return NULL;
ie->indexed_file = 0;
ie->length = length;
ie->key_length = 0;
ie->flags = INDEX_ENTRY_END;
ie->reserved = 0;
return ie;
}
/**
* ntfs_ie_get_vcn - Get the VCN associated with an index entry
* @ie:
*
* Description...
*
* Returns:
*/
VCN ntfs_ie_get_vcn(INDEX_ENTRY *ie)
{
if (!ie)
return -1;
if (!(ie->flags & INDEX_ENTRY_NODE))
return -1;
ntfs_log_trace ("\n");
return *((VCN*) ((u8*) ie + ie->length - 8));
}
/**
* ntfs_ie_copy - Create a copy of an index entry
* @ie:
*
* Description...
*
* Returns:
*/
INDEX_ENTRY * ntfs_ie_copy(INDEX_ENTRY *ie)
{
INDEX_ENTRY *copy = NULL;
if (!ie)
return NULL;
ntfs_log_trace ("\n");
copy = malloc(ie->length);
if (!copy)
return NULL;
memcpy(copy, ie, ie->length);
return copy;
}
/**
* ntfs_ie_set_vcn - Set VCN associated with an index entry
* @ie:
* @vcn:
*
* Description...
*
* Returns:
*/
INDEX_ENTRY * ntfs_ie_set_vcn(INDEX_ENTRY *ie, VCN vcn)
{
if (!ie)
return 0;
ntfs_log_trace ("\n");
if (!(ie->flags & INDEX_ENTRY_NODE)) {
ie->length += 8;
ie = realloc(ie, ie->length);
if (!ie)
return NULL;
ie->flags |= INDEX_ENTRY_NODE;
}
*((VCN*) ((u8*) ie + ie->length - 8)) = vcn;
return ie;
}
/**
* ntfs_ie_remove_vcn - Remove the VCN associated with an index entry
* @ie:
*
* Description...
*
* Returns:
*/
INDEX_ENTRY * ntfs_ie_remove_vcn(INDEX_ENTRY *ie)
{
if (!ie)
return NULL;
if (!(ie->flags & INDEX_ENTRY_NODE))
return ie;
ntfs_log_trace ("\n");
ie->length -= 8;
ie->flags &= ~INDEX_ENTRY_NODE;
ie = realloc(ie, ie->length);
return ie;
}
/**
* ntfs_ie_set_name - Associate a name with an index entry
* @ie:
* @name:
* @namelen:
* @nametype:
*
* Description...
*
* Returns:
*/
INDEX_ENTRY * ntfs_ie_set_name(INDEX_ENTRY *ie, ntfschar *name, int namelen, FILE_NAME_TYPE_FLAGS nametype)
{
FILE_NAME_ATTR *file;
int need;
BOOL wipe = FALSE;
VCN vcn = 0;
if (!ie || !name)
return NULL;
ntfs_log_trace ("\n");
/*
* INDEX_ENTRY
* MFT_REF indexed_file;
* u16 length;
* u16 key_length;
* INDEX_ENTRY_FLAGS flags;
* u16 reserved;
*
* FILENAME
* MFT_REF parent_directory;
* s64 creation_time;
* s64 last_data_change_time;
* s64 last_mft_change_time;
* s64 last_access_time;
* s64 allocated_size;
* s64 data_size;
* FILE_ATTR_FLAGS file_attributes;
* u32 reserved;
* u8 file_name_length;
* FILE_NAME_TYPE_FLAGS file_name_type;
* ntfschar file_name[l];
* u8 reserved[n]
*
* VCN vcn;
*/
//ntfs_log_debug("key length = 0x%02X\n", ie->key_length);
//ntfs_log_debug("new name length = %d\n", namelen);
if (ie->key_length > 0) {
file = &ie->key.file_name;
//ntfs_log_debug("filename, length %d\n", file->file_name_length);
need = ATTR_SIZE(namelen * sizeof(ntfschar) + 2) -
ATTR_SIZE(file->file_name_length * sizeof(ntfschar) + 2);
} else {
//ntfs_log_debug("no filename\n");
need = ATTR_SIZE(sizeof(FILE_NAME_ATTR) + (namelen * sizeof(ntfschar)));
wipe = TRUE;
}
//ntfs_log_debug("need 0x%02X bytes\n", need);
if (need != 0) {
if (ie->flags & INDEX_ENTRY_NODE)
vcn = ntfs_ie_get_vcn(ie);
ie->length += need;
ie->key_length += need;
//ntfs_log_debug("realloc 0x%02X\n", ie->length);
ie = realloc(ie, ie->length);
if (!ie)
return NULL;
if (ie->flags & INDEX_ENTRY_NODE)
ie = ntfs_ie_set_vcn(ie, vcn);
if (wipe)
memset(&ie->key.file_name, 0, sizeof(FILE_NAME_ATTR));
if (need > 0)
memset((u8*)ie + ie->length - need, 0, need);
}
memcpy(ie->key.file_name.file_name, name, namelen * sizeof(ntfschar));
ie->key.file_name.file_name_length = namelen;
ie->key.file_name.file_name_type = nametype;
ie->flags &= ~INDEX_ENTRY_END;
//ntfs_log_debug("ie->length = 0x%02X\n", ie->length);
//ntfs_log_debug("ie->key_length = 0x%02X\n", ie->key_length);
return ie;
}
/**
* ntfs_ie_remove_name - Remove the name from an index-entry
* @ie:
*
* Description...
*
* Returns:
*/
INDEX_ENTRY * ntfs_ie_remove_name(INDEX_ENTRY *ie)
{
VCN vcn = 0;
if (!ie)
return NULL;
if (ie->key_length == 0)
return ie;
ntfs_log_trace ("\n");
if (ie->flags & INDEX_ENTRY_NODE)
vcn = ntfs_ie_get_vcn(ie);
ie->length -= ATTR_SIZE(ie->key_length);
ie->key_length = 0;
ie->flags |= INDEX_ENTRY_END;
ie = realloc(ie, ie->length);
if (!ie)
return NULL;
if (ie->flags & INDEX_ENTRY_NODE)
ie = ntfs_ie_set_vcn(ie, vcn);
return ie;
}
#endif /* NTFS_RICH */
/**
* ntfs_index_root_get - read the index root of an attribute
* @ni: open ntfs inode in which the ntfs attribute resides
@ -979,4 +705,3 @@ out:
return root;
}

View File

@ -1149,140 +1149,3 @@ int ntfs_inode_badclus_bad(u64 mft_no, ATTR_RECORD *attr)
return ret;
}
#ifdef NTFS_RICH
#include "rich.h"
/**
* ntfs_inode_close2 - Close an inode, freeing any resources
* @ni:
*
* Description...
*
* Returns:
*/
int ntfs_inode_close2(ntfs_inode *ni)
{
if (!ni)
return 0;
ntfs_log_trace ("inode %p, mft %lld, refcount %d\n", ni, MREF(ni->mft_no), ni->ref_count);
ni->ref_count--;
if (ni->ref_count > 0)
return 0;
// unlink
// ino->private_data
// XXX temporary until we have commit/rollback
NInoClearDirty(ni);
return ntfs_inode_close(ni);
}
/**
* ntfs_inode_open2 - Open an inode and initialise it
* @vol:
* @mref:
*
* Description...
*
* Returns:
*/
ntfs_inode * ntfs_inode_open2(ntfs_volume *vol, const MFT_REF mref)
{
ntfs_inode *ino = NULL;
struct ntfs_dir *dir;
if (!vol)
return NULL;
ntfs_log_trace ("\n");
switch (mref) {
case FILE_Bitmap: ino = vol->lcnbmp_ni; break;
case FILE_MFT: ino = vol->mft_ni; break;
case FILE_MFTMirr: ino = vol->mftmirr_ni; break;
case FILE_Volume: ino = vol->vol_ni; break;
case FILE_root:
dir = vol->private_data;
if (dir)
ino = dir->inode;
break;
}
if (ino) {
ntfs_log_debug("inode reuse %lld\n", mref);
ino->ref_count++;
return ino;
}
ino = ntfs_inode_open(vol, mref);
if (!ino)
return NULL;
/*
if (mref != FILE_root)
ntfs_inode_dir_map (ino);
*/
// link
// ino->private_data
ino->private_data = NULL;
ino->ref_count = 1;
ntfs_log_debug("inode open %lld, 0x%llx\n", MREF(mref), mref);
return ino;
}
/**
* ntfs_inode_open3 - Open an inode and initialise it
* @vol:
* @mref:
*
* Description...
*
* Returns:
*/
ntfs_inode * ntfs_inode_open3(ntfs_volume *vol, const MFT_REF mref)
{
ntfs_inode *ino = NULL;
if (!vol)
return NULL;
ntfs_log_trace ("\n");
ino = calloc(1, sizeof(*ino));
if (!ino)
return NULL;
ino->mrec = malloc(vol->mft_record_size);
if (!ino->mrec) {
free(ino);
return NULL;
}
ino->mft_no = mref;
ino->vol = vol;
ino->data_size = -1;
ino->allocated_size = -1;
ino->private_data = NULL;
ino->ref_count = 1;
if (1 != ntfs_attr_mst_pread(vol->mft_na, MREF(mref) * vol->mft_record_size, 1, vol->mft_record_size, ino->mrec)) {
//ntfs_inode_close2(ino); ???
free(ino->mrec);
free(ino);
return NULL;
}
NInoSetDirty(ino);
return ino;
}
#endif /* NTFS_RICH */

View File

@ -1555,386 +1555,6 @@ sync_rollback:
return -1;
}
#ifdef NTFS_RICH
#include "bitmap.h"
#include "dir.h"
#include "tree.h"
#include "index.h"
#include "rich.h"
/**
* ntfs_mft_remove_attr - Remove an attribute from an MFT record
* @bmp:
* @inode:
* @type:
*
* Description...
*
* Returns:
*/
int ntfs_mft_remove_attr(struct ntfs_bmp *bmp, ntfs_inode *inode, ATTR_TYPES type)
{
ATTR_RECORD *attr20, *attrXX;
MFT_RECORD *mft;
u8 *src, *dst;
int len;
if (!inode)
return 1;
ntfs_log_trace ("\n");
attr20 = find_first_attribute(AT_ATTRIBUTE_LIST, inode->mrec);
if (attr20)
return 1;
ntfs_log_debug("remove inode %lld, attr 0x%02X\n", inode->mft_no, type);
attrXX = find_first_attribute(type, inode->mrec);
if (!attrXX)
return 1;
if (utils_free_non_residents3(bmp, inode, attrXX))
return 1;
// remove entry
// inode->mrec
mft = inode->mrec;
//utils_dump_mem(mft, 0, mft->bytes_in_use, DM_DEFAULTS); ntfs_log_debug("\n");
//utils_dump_mem(attrXX, 0, attrXX->length, DM_DEFAULTS); ntfs_log_debug("\n");
//ntfs_log_debug("mrec = %p, attr = %p, diff = %d (0x%02X)\n", mft, attrXX, (u8*)attrXX - (u8*)mft, (u8*)attrXX - (u8*)mft);
// memmove
dst = (u8*) attrXX;
src = dst + attrXX->length;
len = (((u8*) mft + mft->bytes_in_use) - src);
// fix mft header
mft->bytes_in_use -= attrXX->length;
#if 0
ntfs_log_debug("dst = 0x%02X, src = 0x%02X, len = 0x%02X\n", (dst - (u8*)mft), (src - (u8*)mft), len);
ntfs_log_debug("attr %02X, len = 0x%02X\n", attrXX->type, attrXX->length);
ntfs_log_debug("bytes in use = 0x%02X\n", mft->bytes_in_use);
ntfs_log_debug("\n");
#endif
memmove(dst, src, len);
//utils_dump_mem(mft, 0, mft->bytes_in_use, DM_DEFAULTS); ntfs_log_debug("\n");
NInoSetDirty(inode);
return 0;
}
/**
* ntfs_mft_add_attr - Add an attribute to an MFT record
* @inode:
* @type:
* @data:
* @data_len:
*
* Description...
*
* Returns:
*/
ATTR_RECORD * ntfs_mft_add_attr(ntfs_inode *inode, ATTR_TYPES type, u8 *data, int data_len)
{
MFT_RECORD *mrec;
ATTR_RECORD *attr;
u8 *ptr;
u8 *src;
u8 *dst;
int len;
int attr_size;
if (!inode)
return NULL;
if (!data)
return NULL;
ntfs_log_trace ("inode %p, mft %lld, attr 0x%02x, len %d\n", inode, inode->mft_no, type, data_len);
attr_size = ATTR_SIZE(data_len);
mrec = inode->mrec;
if (!mrec)
return NULL;
if ((mrec->bytes_in_use + attr_size + 0x18) > mrec->bytes_allocated) {
ntfs_log_debug("attribute is too big to fit in the record\n");
return NULL;
}
ptr = (u8*) inode->mrec + mrec->attrs_offset;
while (1) {
attr = (ATTR_RECORD*) ptr;
if (type < attr->type)
break;
ptr += attr->length;
}
//ntfs_log_debug("insert before attr 0x%02X\n", attr->type);
len = ((u8*) mrec + mrec->bytes_in_use) - ((u8*) attr);
src = (u8*) attr;
dst = src + attr_size + 0x18;
memmove(dst, src, len);
src = data;
dst = (u8*) attr + 0x18;
len = data_len;
// XXX wipe slack space after attr?
memcpy(dst, src, len);
mrec->bytes_in_use += attr_size + 0x18;
memset(attr, 0, 0x18);
*(u32*)((u8*) attr + 0x00) = type;
*(u32*)((u8*) attr + 0x04) = attr_size + 0x18;
*(u16*)((u8*) attr + 0x0E) = mrec->next_attr_instance;
*(u32*)((u8*) attr + 0x10) = data_len;
*(u32*)((u8*) attr + 0x14) = 0x18;
mrec->next_attr_instance++;
return attr;
}
/**
* ntfs_mft_resize_resident - Resize a resident attribute in an MFT record
* @inode:
* @type:
* @name:
* @name_len:
* @data:
* @data_len:
*
* Description...
*
* Returns:
*/
int ntfs_mft_resize_resident(ntfs_inode *inode, ATTR_TYPES type, ntfschar *name, int name_len, u8 *data, int data_len)
{
int mft_size;
int mft_usage;
int mft_free;
int attr_orig;
int attr_new;
u8 *src;
u8 *dst;
u8 *end;
int len;
ntfs_attr_search_ctx *ctx = NULL;
ATTR_RECORD *arec = NULL;
MFT_RECORD *mrec = NULL;
int res = -1;
ntfs_log_trace ("\n");
// XXX only works when attr is in base inode
if ((!inode) || (!inode->mrec))
return -1;
if ((!data) || (data_len < 0))
return -1;
mrec = inode->mrec;
ntfs_log_debug("inode = %lld\n", MREF(inode->mft_no));
//utils_dump_mem(mrec, 0, 1024, DM_DEFAULTS);
mft_size = mrec->bytes_allocated;
mft_usage = mrec->bytes_in_use;
mft_free = mft_size - mft_usage;
//ntfs_log_debug("mft_size = %d\n", mft_size);
//ntfs_log_debug("mft_usage = %d\n", mft_usage);
//ntfs_log_debug("mft_free = %d\n", mft_free);
//ntfs_log_debug("\n");
ctx = ntfs_attr_get_search_ctx(inode, NULL);
if (!ctx)
goto done;
ntfs_name_print(name, name_len);
ntfs_log_debug(" type = 0x%02x\n", type);
if (ntfs_attr_lookup(type, name, name_len, CASE_SENSITIVE, 0, NULL, 0, ctx) != 0)
goto done;
arec = ctx->attr;
if (arec->non_resident) {
ntfs_log_debug("attribute isn't resident\n");
goto done;
}
attr_orig = arec->value_length;
attr_new = data_len;
ntfs_log_debug("attr orig = %d\n", attr_orig);
ntfs_log_debug("attr new = %d\n", attr_new);
//ntfs_log_debug("\n");
if ((attr_new - attr_orig + mft_usage) > mft_size) {
ntfs_log_debug("attribute won't fit into mft record\n");
goto done;
}
//ntfs_log_debug("new free space = %d\n", mft_size - (attr_new - attr_orig + mft_usage));
src = (u8*)arec + arec->length;
dst = src + (attr_new - attr_orig);
end = (u8*)mrec + mft_usage;
len = end - src;
//ntfs_log_debug("src = %d\n", src - (u8*)mrec);
//ntfs_log_debug("dst = %d\n", dst - (u8*)mrec);
//ntfs_log_debug("end = %d\n", end - (u8*)mrec);
//ntfs_log_debug("len = %d\n", len);
if (src != dst)
memmove(dst, src, len);
memcpy((u8*)arec + arec->value_offset, data, data_len);
mrec->bytes_in_use += (attr_new - attr_orig);
arec->length += (attr_new - attr_orig);
arec->value_length += (attr_new - attr_orig);
memset((u8*)mrec + mrec->bytes_in_use, 0, mft_size - mrec->bytes_in_use);
mft_usage += (attr_new - attr_orig);
//utils_dump_mem(mrec, 0, mft_size, DM_DEFAULTS);
res = 0;
done:
ntfs_attr_put_search_ctx(ctx);
return res;
}
/**
* ntfs_mft_free_space - Calculate the free space (bytes) in an MFT record
* @dir:
*
* Description...
*
* Returns:
*/
int ntfs_mft_free_space(struct ntfs_dir *dir)
{
int res = 0;
MFT_RECORD *mft;
if ((!dir) || (!dir->inode))
return -1;
ntfs_log_trace ("\n");
mft = (MFT_RECORD*) dir->inode->mrec;
res = mft->bytes_allocated - mft->bytes_in_use;
return res;
}
/**
* ntfs_mft_add_index - Add an index (directory) to an MFT record
* @dir:
*
* Description...
*
* Returns:
*/
int ntfs_mft_add_index(struct ntfs_dir *dir)
{
ntfs_volume *vol;
u8 *buffer = NULL;
ATTR_RECORD *attr = NULL;
struct ntfs_dt *dt = NULL;
INDEX_ENTRY *ie = NULL;
if (!dir)
return 1;
if (dir->bitmap && dir->ialloc)
return 0;
if (dir->bitmap || dir->ialloc)
return 1;
if (dir->index_size < 512)
return 1;
ntfs_log_trace ("\n");
vol = dir->vol;
ntfs_log_debug("add two attrs to "); ntfs_name_print(dir->name, dir->name_len); ntfs_log_debug("\n");
ntfs_log_debug("index size = %d\n", dir->index_size);
buffer = malloc(dir->index_size);
if (!buffer)
return 1;
dt = ntfs_dt_create(dir, dir->index, -1);
if (!dt)
return 1;
dt->vcn = 0; // New alloc record
ie = ntfs_ie_copy(dir->index->children[dir->index->child_count-1]);
ie = ntfs_ie_set_vcn(ie, dt->vcn);
// can't replace ie yet, there may not be room
ntfs_ie_free(ie);
ntfs_dt_transfer2(dir->index, dt, 0, dir->index->child_count - 1);
ntfs_log_debug("root has %d children\n", dir->index->child_count);
ntfs_log_debug("node has %d children\n", dt->child_count);
ntfs_dt_free(dt);
// create a new dt
// attach dt to dir
// move entries into alloc
// shrink root
// transfer keys to new node
// hook up root & alloc dts
// need disk allocation before here
// Index Allocation
memset(buffer, 0, 128);
attr = ntfs_mft_add_attr(dir->inode, AT_INDEX_ALLOCATION, buffer, 0x48);
// Bitmap
memset(buffer, 0, 8);
buffer[0] = 0x01;
//ntfs_log_debug("inode = %p\n", dir->inode);
attr = ntfs_mft_add_attr(dir->inode, AT_BITMAP, buffer, 8);
// attach alloc and bitmap to dir
// need to create ntfs_attr's for them
// one indx record
// 8 bits of bitmap
if (0) ntfs_bmp_find_space(NULL, 0, 0);
//ntfs_log_debug("m1 = %lld\n", vol->mft_zone_start);
//ntfs_log_debug("m2 = %lld\n", vol->mft_zone_end);
//ntfs_log_debug("m3 = %lld\n", vol->mft_zone_pos);
//ntfs_log_debug("z1 = %lld\n", vol->data1_zone_pos);
//ntfs_log_debug("z2 = %lld\n", vol->data2_zone_pos);
free(buffer);
return 0;
}
#endif /* NTFS_RICH */
/**
* ntfs_mft_usn_dec - Decrement USN by one
* @mrec: pointer to an mft record

View File

@ -1534,368 +1534,3 @@ err_out:
return ret;
}
#ifdef NTFS_RICH
#include "tree.h"
#include "rich.h"
/**
* utils_valid_device - Perform some safety checks on the device before we start
* @name: Full pathname of the device/file to work with
* @force: Continue regardless of problems
*
* Check that the name refers to a device and that is isn't already mounted.
* These checks can be overridden by using the force option.
*
* Return: 1 Success, we can continue
* 0 Error, we cannot use this device
*/
int utils_valid_device(const char *name, int force)
{
unsigned long mnt_flags = 0;
struct stat st;
#ifdef __CYGWIN32__
/* FIXME: This doesn't work for Cygwin, so just return success for now... */
return 1;
#endif
if (!name) {
errno = EINVAL;
return 0;
}
ntfs_log_trace ("\n");
if (stat(name, &st) == -1) {
if (errno == ENOENT) {
ntfs_log_error("The device %s doesn't exist\n", name);
} else {
ntfs_log_perror("Error getting information about %s", name);
}
return 0;
}
if (!S_ISBLK(st.st_mode) && !S_ISREG(st.st_mode)) {
ntfs_log_warning("%s is not a block device, "
"nor regular file.\n", name);
if (!force) {
ntfs_log_error("Use the force option to work with other"
" file types, for your own risk!\n");
return 0;
}
ntfs_log_warning("Forced to continue.\n");
}
/* Make sure the file system is not mounted. */
if (ntfs_check_if_mounted(name, &mnt_flags)) {
ntfs_log_perror("Failed to determine whether %s is mounted", name);
if (!force) {
ntfs_log_error("Use the force option to ignore this error.\n");
return 0;
}
ntfs_log_warning("Forced to continue.\n");
} else if (mnt_flags & NTFS_MF_MOUNTED) {
ntfs_log_warning("The device %s, is mounted.\n", name);
if (!force) {
ntfs_log_error("Use the force option to work a mounted filesystem.\n");
return 0;
}
ntfs_log_warning("Forced to continue.\n");
}
return 1;
}
/**
* utils_mount_volume - Mount an NTFS volume
* @device:
* @flags:
* @force:
*
* Description...
*
* Returns:
*/
ntfs_volume * utils_mount_volume(const char *device, unsigned long flags, BOOL force)
{
ntfs_volume *vol;
if (!device) {
errno = EINVAL;
return NULL;
}
ntfs_log_trace ("\n");
if (!utils_valid_device(device, force))
return NULL;
vol = ntfs_mount(device, flags);
if (!vol) {
int err;
err = errno;
ntfs_log_perror("Couldn't mount device '%s'", device);
if (err == EPERM)
ntfs_log_error("Windows was hibernated. Try to mount "
"volume in windows, shut down and try "
"again.\n");
if (err == EOPNOTSUPP)
ntfs_log_error("Windows did not shut down properly. "
"Try to mount volume in windows, "
"shut down and try again.\n");
return NULL;
}
if (vol->flags & VOLUME_IS_DIRTY) {
ntfs_log_warning("Volume is dirty.\n");
if (!force) {
ntfs_log_error("Run chkdsk and try again, or use the "
"force option.\n");
ntfs_umount(vol, FALSE);
return NULL;
}
ntfs_log_quiet("Forced to continue.\n");
}
return vol;
}
/**
* ntfs_volume_commit - Write to disk the in-memory volume changes
* @vol:
*
* Description...
*
* Returns:
*/
int ntfs_volume_commit(ntfs_volume *vol)
{
if (!vol)
return -1;
ntfs_log_trace ("\n");
ntfs_log_debug("commit volume\n");
if (ntfs_bmp_commit(vol->private_bmp1) < 0)
return -1;
if (ntfs_bmp_commit(vol->private_bmp2) < 0)
return -1;
if (ntfs_dir_commit(vol->private_data) < 0)
return -1;
return 0;
}
/**
* ntfs_volume_rollback - Discard the in-memory volume changes
* @vol:
*
* Description...
*
* Returns:
*/
int ntfs_volume_rollback(ntfs_volume *vol)
{
if (!vol)
return -1;
ntfs_log_trace ("\n");
if (ntfs_bmp_rollback(vol->private_bmp1) < 0)
return -1;
if (ntfs_bmp_rollback(vol->private_bmp2) < 0)
return -1;
if (ntfs_dir_rollback(vol->private_data) < 0)
return -1;
return 0;
}
/**
* ntfs_volume_umount2 - Unmount an NTFS volume, using the new directory support
* @vol:
* @force:
*
* Description...
*
* Returns:
*/
int ntfs_volume_umount2(ntfs_volume *vol, const BOOL force)
{
struct ntfs_dir *dir;
struct ntfs_bmp *bmp;
if (!vol)
return 0;
ntfs_log_trace ("\n");
ntfs_volume_rollback(vol);
dir = (struct ntfs_dir *) vol->private_data;
vol->private_data = NULL;
ntfs_dir_free(dir);
bmp = (struct ntfs_bmp *) vol->private_bmp1;
vol->private_bmp1 = NULL;
ntfs_bmp_free(bmp);
bmp = (struct ntfs_bmp *) vol->private_bmp2;
vol->private_bmp2 = NULL;
ntfs_bmp_free(bmp);
return ntfs_umount(vol, force);
}
/**
* ntfs_volume_mount2 - Mount an NTFS volume, using the new directory support
* @device:
* @flags:
* @force:
*
* Description...
*
* Returns:
*/
ntfs_volume * ntfs_volume_mount2(const char *device, unsigned long flags, BOOL force)
{
// XXX can we replace these and search by mft number? Hmm... NO.
// unless I have a recursive search for an MFT number
static ntfschar bmp[8] = {
const_cpu_to_le16('$'),
const_cpu_to_le16('B'),
const_cpu_to_le16('i'),
const_cpu_to_le16('t'),
const_cpu_to_le16('m'),
const_cpu_to_le16('a'),
const_cpu_to_le16('p'),
const_cpu_to_le16(0)
};
static ntfschar mft[5] = {
const_cpu_to_le16('$'),
const_cpu_to_le16('M'),
const_cpu_to_le16('F'),
const_cpu_to_le16('T'),
const_cpu_to_le16(0)
};
static ntfschar mftmirr[9] = {
const_cpu_to_le16('$'),
const_cpu_to_le16('M'),
const_cpu_to_le16('F'),
const_cpu_to_le16('T'),
const_cpu_to_le16('M'),
const_cpu_to_le16('i'),
const_cpu_to_le16('r'),
const_cpu_to_le16('r'),
const_cpu_to_le16(0)
};
static ntfschar dot[2] = {
const_cpu_to_le16('.'),
const_cpu_to_le16(0)
};
ntfs_volume *vol;
struct ntfs_dir *dir;
struct ntfs_dt *root;
struct ntfs_dt *found;
int num;
ntfs_log_trace ("\n");
vol = utils_mount_volume(device, flags, force);
if (!vol)
return NULL;
vol->lcnbmp_ni ->ref_count = 1;
vol->mft_ni ->ref_count = 1;
vol->mftmirr_ni->ref_count = 1;
vol->lcnbmp_ni ->private_data = NULL;
vol->mft_ni ->private_data = NULL;
vol->mftmirr_ni->private_data = NULL;
dir = ntfs_dir_create(vol, FILE_root);
if (!dir) {
ntfs_volume_umount2(vol, FALSE);
vol = NULL;
goto done;
}
dir->index = ntfs_dt_create(dir, NULL, -1);
root = dir->index;
//$Bitmap
num = -1;
found = ntfs_dt_find2(root, bmp, (sizeof(bmp)/sizeof(ntfschar)) - 1, &num);
if ((!found) || (num < 0)) {
ntfs_log_debug("can't find $Bitmap\n");
ntfs_volume_umount2(vol, FALSE);
vol = NULL;
goto done;
}
vol->lcnbmp_ni->ref_count++;
vol->lcnbmp_ni->private_data = found->dir;
found->inodes[num] = vol->lcnbmp_ni;
//$MFT
num = -1;
found = ntfs_dt_find2(root, mft, (sizeof(mft)/sizeof(ntfschar)) - 1, &num);
if ((!found) || (num < 0)) {
ntfs_log_debug("can't find $MFT\n");
ntfs_volume_umount2(vol, FALSE);
vol = NULL;
goto done;
}
vol->mft_ni->ref_count++;
vol->mft_ni->private_data = found->dir;
found->inodes[num] = vol->mft_ni;
//$MFTMirr
num = -1;
found = ntfs_dt_find2(root, mftmirr, (sizeof(mftmirr)/sizeof(ntfschar)) - 1, &num);
if ((!found) || (num < 0)) {
ntfs_log_debug("can't find $MFTMirr\n");
ntfs_volume_umount2(vol, FALSE);
vol = NULL;
goto done;
}
vol->mftmirr_ni->ref_count++;
vol->mftmirr_ni->private_data = found->dir;
found->inodes[num] = vol->mftmirr_ni;
// root directory
num = -1;
found = ntfs_dt_find2(root, dot, (sizeof(dot)/sizeof(ntfschar)) - 1, &num);
if ((!found) || (num < 0)) {
ntfs_log_debug("can't find the root directory\n");
ntfs_volume_umount2(vol, FALSE);
vol = NULL;
goto done;
}
vol->private_data = found->dir;
found->inodes[num] = dir->inode;
dir->inode->private_data = found;
dir->inode->ref_count = 2;
vol->private_bmp1 = ntfs_bmp_create(vol->mft_ni, AT_BITMAP, NULL, 0);
vol->private_bmp2 = ntfs_bmp_create(vol->lcnbmp_ni, AT_DATA, NULL, 0);
if (!vol->private_bmp1 || !vol->private_bmp2) {
ntfs_log_debug("can't find the bitmaps\n");
ntfs_volume_umount2(vol, FALSE);
vol = NULL;
goto done;
}
done:
return vol;
}
#endif /* NTFS_RICH */

View File

@ -37,10 +37,6 @@ if ENABLE_CRYPTO
EXTRA_PROGRAMS += ntfsdecrypt
endif
if ENABLE_RICH
EXTRA_PROGRAMS += ntfsrm
endif
# Set the include path.
AM_CPPFLAGS = -I$(top_srcdir)/include/ntfs $(all_includes)
@ -101,12 +97,6 @@ ntfscmp_LDFLAGS = $(AM_LFLAGS)
# We don't distribute these
if ENABLE_RICH
ntfsrm_SOURCES = ntfsrm.c ntfsrm.h utils.c utils.h
ntfsrm_LDADD = $(AM_LIBS)
ntfsrm_LDFLAGS = $(AM_LFLAGS)
endif
ntfstruncate_SOURCES = attrdef.c ntfstruncate.c utils.c utils.h
ntfstruncate_LDADD = $(AM_LIBS)
ntfstruncate_LDFLAGS = $(AM_LFLAGS)

View File

@ -98,7 +98,6 @@ int utils_set_locale(void)
}
}
#ifndef NTFS_RICH
/**
* utils_valid_device - Perform some safety checks on the device, before we start
* @name: Full pathname of the device/file to work with
@ -210,8 +209,6 @@ ntfs_volume * utils_mount_volume(const char *device, unsigned long flags, BOOL f
return vol;
}
#endif
/**
* utils_parse_size - Convert a string representing a size
* @value: String to be parsed
@ -333,7 +330,6 @@ int utils_parse_range(const char *string, s64 *start, s64 *finish, BOOL scale)
return 1;
}
#ifndef NTFS_RICH
/**
* find_attribute - Find an attribute of the given type
* @type: An attribute type, e.g. AT_FILE_NAME
@ -403,7 +399,6 @@ ATTR_RECORD * find_first_attribute(const ATTR_TYPES type, MFT_RECORD *mft)
return rec;
}
#endif
/**
* utils_inode_get_name
*

View File

@ -52,15 +52,11 @@ int utils_mftrec_in_use(ntfs_volume *vol, MFT_REF mref);
int utils_is_metadata(ntfs_inode *inode);
void utils_dump_mem(void *buf, int start, int length, int flags);
#ifndef _NTFS_RICH_H_
ATTR_RECORD * find_attribute(const ATTR_TYPES type, ntfs_attr_search_ctx *ctx);
ATTR_RECORD * find_first_attribute(const ATTR_TYPES type, MFT_RECORD *mft);
#endif
#if !(defined(_NTFS_VOLUME_H) && defined(NTFS_RICH))
int utils_valid_device(const char *name, int force);
ntfs_volume * utils_mount_volume(const char *device, unsigned long flags, BOOL force);
#endif
/**
* defines...