- Added dumping of index records from $INDEX_ROOT and $INDEX_ALLOCATION

- Changed message for resident $INDEX_ALLOCION to print error, because it shouldn't be resident

(Logical change 1.536)
edge.strict_endians
(none)!yura 2004-09-08 16:27:54 +00:00
parent 682a037a7f
commit 3d8ff9eb46
1 changed files with 228 additions and 7 deletions

View File

@ -99,6 +99,7 @@ static void version (void)
printf (" 2002-2004 Anton Altaparmakov\n");
printf (" 2002-2003 Richard Russon\n");
printf (" 2003 Leonard Norrgård\n");
printf (" 2004 Yura Pakhuchiy\n");
printf ("\n%s\n%s%s\n", ntfs_gpl, ntfs_bugs, ntfs_home);
}
@ -894,6 +895,77 @@ static void ntfs_dump_attr_data(ATTR_RECORD *attr, ntfs_volume *vol)
}
}
/**
* ntfs_dump_index_entries()
*
* dump sequence of index_entries and return number of entries dumped.
*/
static int ntfs_dump_index_entries(INDEX_ENTRY *entry, ATTR_TYPES type)
{
int numb_entries = 1;
char *name = NULL;
Vprintf("\tDumping index entries:");
while(1) {
if (!opts.verbose) {
if (entry->flags & INDEX_ENTRY_END)
break;
entry = (INDEX_ENTRY *)((u8 *)entry +
le16_to_cpu(entry->length));
numb_entries++;
continue;
}
Vprintf("\n");
Vprintf("\t\tEntry length:\t\t %u\n",
le16_to_cpu(entry->length));
Vprintf("\t\tKey length:\t\t %u\n",
le16_to_cpu(entry->key_length));
Vprintf("\t\tFlags:\t\t\t 0x%02x\n", le16_to_cpu(entry->flags));
if (entry->flags & INDEX_ENTRY_END)
break;
switch(type) {
case(AT_FILE_NAME):
Vprintf("\t\tFILE record number:\t %llu\n",
MREF_LE(entry->indexed_file));
Vprintf("\t\tFile attributes:\t 0x%02x\n",
le32_to_cpu(
entry->key.file_name.file_attributes));
Vprintf("\t\tFile name namespace:\t 0x%02x\n",
entry->key.file_name.file_name_type);
ntfs_ucstombs(entry->key.file_name.file_name,
entry->key.file_name.file_name_length,
&name, 0);
Vprintf("\t\tName:\t\t\t %s\n", name);
free(name);
name = NULL;
Vprintf("\t\tParent directory:\t %lld\n",
MREF_LE(entry->
key.file_name.parent_directory));
Vprintf("\t\tData size:\t\t %lld\n",
sle64_to_cpu(
entry->key.file_name.data_size));
Vprintf("\t\tAllocated size:\t\t %lld\n",
sle64_to_cpu(
entry->key.file_name.allocated_size));
break;
default:
// TODO: determine more attribute types
Vprintf("\t\tData offset:\t\t %u\n",
le16_to_cpu(entry->data_offset));
Vprintf("\t\tData length:\t\t %u\n",
le16_to_cpu(entry->data_length));
break;
}
entry = (INDEX_ENTRY *)((u8 *)entry +
le16_to_cpu(entry->length));
numb_entries++;
}
Vprintf("\tEnd of index block reached\n");
return numb_entries;
}
/**
* ntfs_dump_attr_index_root()
*
@ -903,6 +975,7 @@ static void ntfs_dump_attr_index_root(ATTR_RECORD *attr)
{
unsigned int type;
INDEX_ROOT *index_root = NULL;
INDEX_ENTRY *entry;
index_root = (INDEX_ROOT*)((u8*)attr + le16_to_cpu(attr->value_offset));
@ -962,7 +1035,156 @@ static void ntfs_dump_attr_index_root(ATTR_RECORD *attr)
/* the flags are 8bit long, no need for byte-order handling */
printf("\tFlags:\t\t\t 0x%02x\n",index_root->index.flags);
/* printf("\tIndex Entries Following\t %u\n", ???? );*/
entry = (INDEX_ENTRY *)((u8 *)index_root +
le32_to_cpu(index_root->index.entries_offset) + 0x10);
printf("\tIndex entries total:\t %d\n",
ntfs_dump_index_entries(entry, index_root->type));
}
/**
* ntfs_dump_attr_index_allocation()
*
* determine size and type of INDX record
*/
static void get_type_and_size_of_indx(ntfs_inode *ni, ATTR_RECORD *attr,
ATTR_TYPES *type, u32 *size)
{
ntfs_attr_search_ctx *ctx;
ntfschar *name = 0;
INDEX_ROOT *root;
if (attr->name_length) {
name = malloc(attr->name_length * sizeof(ntfschar));
if (!name) {
perror("malloc failed");
return;
}
memcpy(name, (u8 *)attr + attr->name_offset,
attr->name_length * sizeof(ntfschar));
}
ctx = ntfs_attr_get_search_ctx(ni, 0);
if (!ctx) {
perror("ntfs_get_search_ctx failed");
free(name);
return;
}
if (ntfs_attr_lookup(AT_INDEX_ROOT, name, attr->name_length, 0,
0, NULL, 0, ctx)) {
perror("ntfs_attr_lookup failed");
ntfs_attr_put_search_ctx(ctx);
free(name);
return;
}
root = (INDEX_ROOT*)((u8*)ctx->attr +
le16_to_cpu(ctx->attr->value_offset));
*size = le32_to_cpu(root->index_block_size);
*type = root->type;
ntfs_attr_put_search_ctx(ctx);
free(name);
}
/**
* ntfs_dump_attr_index_allocation()
*
* dump context of the index_allocation attribute
*/
static void ntfs_dump_index_allocation(ATTR_RECORD *attr, ntfs_inode *ni)
{
INDEX_ALLOCATION *allocation, *tmp_alloc;
INDEX_ENTRY *entry;
ATTR_TYPES type;
u32 indx_record_size;
int total_entries = 0;
int total_indx_blocks = 0;
ntfs_attr *na;
u8 *bitmap, *byte;
int bit;
ntfschar *name;
get_type_and_size_of_indx(ni, attr, &type, &indx_record_size);
name = malloc(attr->name_length * sizeof(ntfschar));
if (!name) {
perror("malloc failed");
return;
}
memcpy(name, (u8 *)attr + attr->name_offset,
attr->name_length * sizeof(ntfschar));
na = ntfs_attr_open(ni, AT_BITMAP, name, attr->name_length);
if (!na) {
perror("ntfs_attr_open failed");
free(name);
return;
}
bitmap = malloc(na->data_size);
if (!bitmap) {
perror("malloc failed");
free(name);
return;
}
if (ntfs_attr_pread(na, 0, na->data_size, bitmap) != na->data_size) {
perror("ntfs_attr_pread failed");
free(bitmap);
free(name);
return;
}
ntfs_attr_close(na);
byte = bitmap;
name = malloc(attr->name_length * sizeof(ntfschar));
if (!name) {
perror("malloc failed");
return;
}
memcpy(name, (u8 *)attr + attr->name_offset,
attr->name_length * sizeof(ntfschar));
na = ntfs_attr_open(ni, AT_INDEX_ALLOCATION, name, attr->name_length);
if (!na) {
perror("ntfs_attr_open failed");
free(name);
free(bitmap);
return;
}
allocation = malloc(na->data_size);
if (!allocation) {
perror("malloc failed");
free(name);
free(bitmap);
return;
}
if (ntfs_attr_pread(na, 0, na->data_size, allocation)
!= na->data_size) {
perror("ntfs_attr_pread failed");
free(name);
free(allocation);
free(bitmap);
return;
}
ntfs_attr_close(na);
tmp_alloc = allocation;
bit = 0;
while((u8 *)tmp_alloc < (u8 *)allocation + na->data_size) {
if (*byte & (1 << bit)) {
entry = (INDEX_ENTRY *)((u8 *)tmp_alloc + le32_to_cpu(
tmp_alloc->index.entries_offset) + 0x18);
total_entries += ntfs_dump_index_entries(entry, type);
total_indx_blocks++;
}
tmp_alloc = (INDEX_ALLOCATION *)((u8 *)tmp_alloc +
indx_record_size);
bit++;
if (bit > 7) {
bit = 0;
byte++;
}
}
printf("\tIndex entries total:\t %d\n", total_entries);
printf("\tINDX blocks total:\t %d\n", total_indx_blocks);
free(allocation);
free(bitmap);
}
/**
@ -970,7 +1192,7 @@ static void ntfs_dump_attr_index_root(ATTR_RECORD *attr)
*
* dump the index_allocation attribute
*/
static void ntfs_dump_attr_index_allocation(ATTR_RECORD *attr)
static void ntfs_dump_attr_index_allocation(ATTR_RECORD *attr, ntfs_inode *ni)
{
printf("Dumping attribute $INDEX_ALLOCATION (0xA0)\n");
@ -999,12 +1221,11 @@ static void ntfs_dump_attr_index_allocation(ATTR_RECORD *attr)
printf("\tUsed data size:\t\t %llu\n",
(unsigned long long)le64_to_cpu(attr->data_size));
} else {
/* print only the payload's size */
printf("\tValue's size:\t\t %u\n",
(unsigned int)le32_to_cpu(attr->value_length));
Eprintf("Invalid $INDEX_ALLOCTION attribute. Should be be"
" non-resident\n");
}
/* TODO: parse how many records does this B-*+/Tree contains */
ntfs_dump_index_allocation(attr, ni);
}
/**
@ -1305,7 +1526,7 @@ static void ntfs_dump_file_attributes(ntfs_inode *inode)
ntfs_dump_attr_index_root(ctx->attr);
break;
case AT_INDEX_ALLOCATION:
ntfs_dump_attr_index_allocation(ctx->attr);
ntfs_dump_attr_index_allocation(ctx->attr, inode);
break;
case AT_BITMAP:
ntfs_dump_attr_bitmap(ctx->attr);