parent
6e698185ad
commit
4764e7ad65
|
@ -197,6 +197,7 @@ static int parse_options (int argc, char **argv)
|
|||
|
||||
struct ntfs_dir;
|
||||
static void ntfs_ie_dump (INDEX_ENTRY *ie);
|
||||
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);
|
||||
|
||||
/**
|
||||
|
@ -322,7 +323,7 @@ static int ntfs_dt_count_root (struct ntfs_dt *dt)
|
|||
{
|
||||
u8 *buffer = NULL;
|
||||
u8 *ptr = NULL;
|
||||
VCN *vcn = NULL;
|
||||
VCN vcn;
|
||||
s64 size = 0;
|
||||
char *name = NULL;
|
||||
|
||||
|
@ -354,8 +355,8 @@ static int ntfs_dt_count_root (struct ntfs_dt *dt)
|
|||
dt->children = ntfs_dt_alloc_children (dt->children, dt->child_count);
|
||||
|
||||
if (entry->flags & INDEX_ENTRY_NODE) {
|
||||
vcn = (VCN *) (ptr + ((entry->key_length + 0x17) & ~7));
|
||||
//printf ("VCN %lld\n", *vcn);
|
||||
vcn = ntfs_ie_get_vcn ((INDEX_ENTRY*) ptr);
|
||||
//printf ("VCN %lld\n", vcn);
|
||||
}
|
||||
|
||||
if (!(entry->flags & INDEX_ENTRY_END)) {
|
||||
|
@ -387,7 +388,7 @@ static int ntfs_dt_count_alloc (struct ntfs_dt *dt)
|
|||
{
|
||||
u8 *buffer = NULL;
|
||||
u8 *ptr = NULL;
|
||||
VCN *vcn = NULL;
|
||||
VCN vcn;
|
||||
s64 size = 0;
|
||||
char *name = NULL;
|
||||
|
||||
|
@ -416,8 +417,8 @@ static int ntfs_dt_count_alloc (struct ntfs_dt *dt)
|
|||
dt->children = ntfs_dt_alloc_children (dt->children, dt->child_count);
|
||||
|
||||
if (entry->flags & INDEX_ENTRY_NODE) {
|
||||
vcn = (VCN *) (ptr + ((entry->key_length + 0x17) & ~7));
|
||||
//printf ("\tVCN %lld\n", *vcn);
|
||||
vcn = ntfs_ie_get_vcn ((INDEX_ENTRY*) ptr);
|
||||
//printf ("\tVCN %lld\n", vcn);
|
||||
}
|
||||
|
||||
dt->children[dt->child_count-1] = entry;
|
||||
|
@ -608,7 +609,7 @@ static MFT_REF ntfs_dt_find (struct ntfs_dt *dt, ntfschar *name, int name_len)
|
|||
//printf ("map & recurse\n");
|
||||
//printf ("sub %p\n", dt->sub_nodes);
|
||||
if (!dt->sub_nodes[i]) {
|
||||
vcn = *(VCN*)(((u8*)ie) + ie->length - sizeof (VCN));
|
||||
vcn = ntfs_ie_get_vcn (ie);
|
||||
//printf ("vcn = %lld\n", vcn);
|
||||
sub = ntfs_dt_alloc (dt->dir, dt, vcn);
|
||||
dt->sub_nodes[i] = sub;
|
||||
|
@ -673,7 +674,7 @@ static struct ntfs_dt * ntfs_dt_find2 (struct ntfs_dt *dt, ntfschar *name, int n
|
|||
continue;
|
||||
} else if (r == 0) {
|
||||
res = dt;
|
||||
//printf ("match %lld\n", res);
|
||||
//printf ("match %p\n", res);
|
||||
if (index_num)
|
||||
*index_num = i;
|
||||
} else if (r == -1) {
|
||||
|
@ -746,6 +747,72 @@ static struct ntfs_dt * ntfs_dt_find3 (struct ntfs_dt *dt, ntfschar *name, int n
|
|||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_dt_find4
|
||||
* find successor
|
||||
*/
|
||||
static struct ntfs_dt * ntfs_dt_find4 (struct ntfs_dt *dt, ntfschar *name, int name_len, int *index_num)
|
||||
{
|
||||
struct ntfs_dt *res = NULL;
|
||||
struct ntfs_dt *sub = NULL;
|
||||
INDEX_ENTRY *ie;
|
||||
VCN vcn;
|
||||
int i;
|
||||
int r;
|
||||
|
||||
if (!dt || !name)
|
||||
return NULL;
|
||||
|
||||
//printf ("child_count = %d\n", dt->child_count);
|
||||
for (i = 0; i < dt->child_count; i++) {
|
||||
ie = dt->children[i];
|
||||
|
||||
if (ie->flags & INDEX_ENTRY_END) {
|
||||
r = -1;
|
||||
} else {
|
||||
//printf ("\t"); ntfs_name_print (ie->key.file_name.file_name, ie->key.file_name.file_name_length); printf ("\n");
|
||||
r = ntfs_names_collate (name, name_len,
|
||||
ie->key.file_name.file_name,
|
||||
ie->key.file_name.file_name_length,
|
||||
2, IGNORE_CASE,
|
||||
dt->dir->vol->upcase,
|
||||
dt->dir->vol->upcase_len);
|
||||
}
|
||||
|
||||
//printf ("%d, %d\n", i, r);
|
||||
|
||||
if (r == 1) {
|
||||
//printf ("keep searching\n");
|
||||
} else if (r == 0) {
|
||||
//res = dt;
|
||||
//printf ("match\n");
|
||||
// ignore
|
||||
} else if (r == -1) {
|
||||
if (ie->flags & INDEX_ENTRY_NODE) {
|
||||
//printf ("recurse\n");
|
||||
if (!dt->sub_nodes[i]) {
|
||||
vcn = ntfs_ie_get_vcn (ie);
|
||||
//printf ("vcn = %lld\n", vcn);
|
||||
sub = ntfs_dt_alloc (dt->dir, dt, vcn);
|
||||
dt->sub_nodes[i] = sub;
|
||||
}
|
||||
res = ntfs_dt_find4 (dt->sub_nodes[i], name, name_len, index_num);
|
||||
} else {
|
||||
//printf ("no match\n");
|
||||
res = dt;
|
||||
if (index_num)
|
||||
*index_num = i;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
printf ("error collating name\n");
|
||||
}
|
||||
//break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ntfs_dir_alloc
|
||||
|
@ -1125,7 +1192,7 @@ static int ntfs_mft_resize_resident (ntfs_inode *inode, ATTR_TYPES type, ntfscha
|
|||
arec = ctx->attr;
|
||||
|
||||
if (arec->non_resident) {
|
||||
printf ("attributes isn't resident\n");
|
||||
printf ("attribute isn't resident\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1177,28 +1244,16 @@ done:
|
|||
*/
|
||||
static int ntfs_mft_free_space (struct ntfs_dir *dir)
|
||||
{
|
||||
u8 *buffer = NULL;
|
||||
ntfs_volume *vol;
|
||||
int res = 0;
|
||||
MFT_RECORD *mft;
|
||||
|
||||
if (!dir)
|
||||
if ((!dir) || (!dir->inode))
|
||||
return -1;
|
||||
|
||||
buffer = malloc (512);
|
||||
if (!buffer)
|
||||
return -1;
|
||||
|
||||
vol = dir->vol;
|
||||
|
||||
if (ntfs_attr_pread (vol->mft_na, dir->mft_num << vol->mft_record_size_bits, 512, buffer) != 512)
|
||||
goto done;
|
||||
|
||||
mft = (MFT_RECORD*) buffer;
|
||||
mft = (MFT_RECORD*) dir->inode->mrec;
|
||||
|
||||
res = mft->bytes_allocated - mft->bytes_in_use;
|
||||
done:
|
||||
free (buffer);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1726,7 +1781,6 @@ close:
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ntfsrm
|
||||
*/
|
||||
|
@ -1843,8 +1897,7 @@ static void ntfs_ie_dump (INDEX_ENTRY *ie)
|
|||
}
|
||||
}
|
||||
if (ie->flags == INDEX_ENTRY_NODE) {
|
||||
VCN *vcn = (VCN*) ((u8*) ie + ie->length - 8);
|
||||
printf ("child vcn = %lld\n", *vcn);
|
||||
printf ("child vcn = %lld\n", ntfs_ie_get_vcn (ie));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1888,27 +1941,24 @@ static INDEX_ENTRY * ntfs_ie_copy (INDEX_ENTRY *ie)
|
|||
}
|
||||
|
||||
/**
|
||||
* ntfs_ie_set_child
|
||||
* ntfs_ie_set_vcn
|
||||
*/
|
||||
static INDEX_ENTRY * ntfs_ie_set_child (INDEX_ENTRY *ie, VCN vcn)
|
||||
static INDEX_ENTRY * ntfs_ie_set_vcn (INDEX_ENTRY *ie, VCN vcn)
|
||||
{
|
||||
if (!ie)
|
||||
return 0;
|
||||
|
||||
if (ie->flags & INDEX_ENTRY_NODE) {
|
||||
*((VCN*) ((u8*) ie + ie->length - 8)) = vcn;
|
||||
return ie;
|
||||
if (!(ie->flags & INDEX_ENTRY_NODE)) {
|
||||
ie->length += 8;
|
||||
ie = realloc (ie, ie->length);
|
||||
if (!ie)
|
||||
return NULL;
|
||||
|
||||
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 0;
|
||||
return ie;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1976,7 +2026,7 @@ static INDEX_ENTRY * ntfs_ie_set_name (INDEX_ENTRY *ie, ntfschar *name, int name
|
|||
//printf ("need = %d\n", need);
|
||||
|
||||
if (ie->flags & INDEX_ENTRY_NODE)
|
||||
vcn = *((VCN*) ((u8*) ie + ie->length - 8));
|
||||
vcn = ntfs_ie_get_vcn (ie);
|
||||
|
||||
ie->length = 16 + need;
|
||||
ie->key_length = sizeof (FILE_NAME_ATTR) + (namelen * sizeof (ntfschar));
|
||||
|
@ -1987,7 +2037,7 @@ static INDEX_ENTRY * ntfs_ie_set_name (INDEX_ENTRY *ie, ntfschar *name, int name
|
|||
memcpy (ie->key.file_name.file_name, name, namelen * 2);
|
||||
|
||||
if (ie->flags & INDEX_ENTRY_NODE)
|
||||
*((VCN*) ((u8*) ie + ie->length - 8)) = vcn;
|
||||
ie = ntfs_ie_set_vcn (ie, vcn);
|
||||
|
||||
ie->key.file_name.file_name_length = namelen;
|
||||
ie->key.file_name.file_name_type = nametype;
|
||||
|
@ -2009,7 +2059,7 @@ static INDEX_ENTRY * ntfs_ie_remove_name (INDEX_ENTRY *ie)
|
|||
return ie;
|
||||
|
||||
if (ie->flags & INDEX_ENTRY_NODE)
|
||||
vcn = *((VCN*) ((u8*) ie + ie->length - 8));
|
||||
vcn = ntfs_ie_get_vcn (ie);
|
||||
|
||||
ie->length -= ATTR_SIZE (ie->key_length);
|
||||
ie->key_length = 0;
|
||||
|
@ -2020,7 +2070,7 @@ static INDEX_ENTRY * ntfs_ie_remove_name (INDEX_ENTRY *ie)
|
|||
return NULL;
|
||||
|
||||
if (ie->flags & INDEX_ENTRY_NODE)
|
||||
*((VCN*) ((u8*) ie + ie->length - 8)) = vcn;
|
||||
ie = ntfs_ie_set_vcn (ie, vcn);
|
||||
return ie;
|
||||
}
|
||||
|
||||
|
@ -2067,12 +2117,12 @@ static int ntfs_ie_test (void)
|
|||
}
|
||||
|
||||
if (1) {
|
||||
ntfs_ie_set_child (ie1, 1234);
|
||||
ie1 = ntfs_ie_set_vcn (ie1, 1234);
|
||||
ntfs_ie_dump (ie1);
|
||||
}
|
||||
|
||||
if (1) {
|
||||
ntfs_ie_remove_child (ie1);
|
||||
ie1 = ntfs_ie_remove_child (ie1);
|
||||
ntfs_ie_dump (ie1);
|
||||
}
|
||||
|
||||
|
@ -2092,6 +2142,17 @@ static int ntfs_ie_test (void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_ie_get_vcn
|
||||
*/
|
||||
static VCN ntfs_ie_get_vcn (INDEX_ENTRY *ie)
|
||||
{
|
||||
if (!ie)
|
||||
return -1;
|
||||
|
||||
return *((VCN*) ((u8*) ie + ie->length - 8));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ntfs_index_dump_alloc
|
||||
|
@ -2261,6 +2322,98 @@ done:
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfsrm2
|
||||
*/
|
||||
static int ntfsrm2 (ntfs_volume *vol, char *name)
|
||||
{
|
||||
struct ntfs_dir *root_dir = NULL;
|
||||
struct ntfs_dir *find_dir = NULL;
|
||||
struct ntfs_dt *del = NULL;
|
||||
struct ntfs_dt *suc = NULL;
|
||||
MFT_REF mft_num;
|
||||
ntfschar *uname = NULL;
|
||||
int del_num = 0;
|
||||
int suc_num = 0;
|
||||
int len;
|
||||
VCN vcn;
|
||||
INDEX_ENTRY *del_ie = NULL;
|
||||
INDEX_ENTRY *suc_ie = NULL;
|
||||
|
||||
root_dir = ntfs_dir_alloc (vol, FILE_root);
|
||||
if (!root_dir)
|
||||
return 1;
|
||||
|
||||
mft_num = utils_pathname_to_mftref (vol, root_dir, name, &find_dir);
|
||||
|
||||
if (!find_dir) {
|
||||
printf ("Couldn't find the index entry for %s\n", name);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (rindex (name, PATH_SEP))
|
||||
name = rindex (name, PATH_SEP) + 1;
|
||||
|
||||
len = ntfs_mbstoucs (name, &uname, 0);
|
||||
if (len < 0)
|
||||
goto done;
|
||||
|
||||
del = ntfs_dt_find2 (find_dir->index, uname, len, &del_num);
|
||||
if (!del) {
|
||||
printf ("can't find item to delete\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
del_ie = del->children[del_num];
|
||||
utils_dump_mem ((u8*)del_ie, 0, del_ie->length, 1);
|
||||
printf ("\n");
|
||||
|
||||
if (del->header->flags & INDEX_NODE) {
|
||||
printf ("node\n");
|
||||
|
||||
vcn = ntfs_ie_get_vcn (del_ie);
|
||||
//printf ("vcn = %lld\n", vcn);
|
||||
|
||||
suc = ntfs_dt_find4 (find_dir->index, uname, len, &suc_num);
|
||||
//printf ("succ = %p, index = %d\n", suc, suc_num);
|
||||
printf ("\n");
|
||||
|
||||
suc_ie = ntfs_ie_copy ((INDEX_ENTRY*) suc->children[suc_num]);
|
||||
//utils_dump_mem ((u8*)suc_ie, 0, suc_ie->length, 1);
|
||||
//printf ("\n");
|
||||
|
||||
suc_ie = ntfs_ie_set_vcn (suc_ie, vcn);
|
||||
utils_dump_mem ((u8*)suc_ie, 0, suc_ie->length, 1);
|
||||
printf ("\n");
|
||||
|
||||
if (del_ie->length != suc_ie->length) {
|
||||
printf ("realloc!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy (del->children[del_num], suc_ie, suc_ie->length);
|
||||
|
||||
ntfs_mft_resize_resident (find_dir->inode, AT_INDEX_ROOT, I30, 4, (u8*)del->data, del->data_len);
|
||||
//utils_dump_mem ((u8*)find_dir->inode->mrec, 0, 1024, 1);
|
||||
|
||||
//commit
|
||||
|
||||
// Continue delete with the original successor
|
||||
del = suc;
|
||||
del_num = suc_num;
|
||||
}
|
||||
|
||||
//remove key
|
||||
|
||||
//if (!empty)
|
||||
// done
|
||||
|
||||
done:
|
||||
ntfs_dir_free (root_dir);
|
||||
free (uname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* main - Begin here
|
||||
|
@ -2308,7 +2461,8 @@ int main (int argc, char *argv[])
|
|||
if (0) result = ntfs_index_dump (inode);
|
||||
if (0) result = ntfsrm (vol, opts.file);
|
||||
if (0) result = ntfs_ie_test();
|
||||
if (1) result = ntfsadd (vol, opts.file);
|
||||
if (0) result = ntfsadd (vol, opts.file);
|
||||
if (1) result = ntfsrm2 (vol, opts.file);
|
||||
|
||||
done:
|
||||
ntfs_inode_close (inode);
|
||||
|
|
Loading…
Reference in New Issue