first draft of mft search contexts

(Logical change 1.199)
edge.strict_endians
flatcap.org!ntfs 2003-10-11 15:31:25 +00:00
parent a4f7f86a7b
commit ecbe65ac6b
2 changed files with 178 additions and 0 deletions

View File

@ -833,6 +833,155 @@ int utils_is_metadata (ntfs_inode *inode)
}
/**
* mft_get_search_ctx
*/
struct mft_search_ctx * mft_get_search_ctx (ntfs_volume *vol)
{
struct mft_search_ctx *ctx;
ctx = calloc (1, sizeof *ctx);
ctx->mft_num = -1;
ctx->vol = vol;
return ctx;
}
/**
* mft_put_search_ctx
*/
void mft_put_search_ctx (struct mft_search_ctx *ctx)
{
if (!ctx)
return;
if (ctx->inode)
ntfs_inode_close (ctx->inode);
free (ctx);
}
/**
* mft_next_record
*/
int mft_next_record (struct mft_search_ctx *ctx)
{
ATTR_RECORD *attr10 = NULL;
ATTR_RECORD *attr20 = NULL;
ATTR_RECORD *attr80 = NULL;
ntfs_attr_search_ctx *attr_ctx;
if (!ctx)
return -1;
if (ctx->inode) {
ntfs_inode_close (ctx->inode);
ctx->inode = NULL;
}
for (ctx->mft_num++; ctx->mft_num < ctx->vol->nr_mft_records; ctx->mft_num++) {
ctx->flags_match = 0;
int in_use = utils_mftrec_in_use (ctx->vol, (MFT_REF) ctx->mft_num);
if (in_use == -1) {
Eprintf ("Error reading inode %lld. Aborting.", ctx->mft_num);
return -1;
}
if (in_use) {
ctx->flags_match |= FEMR_IN_USE;
ctx->inode = ntfs_inode_open (ctx->vol, (MFT_REF) ctx->mft_num);
if (ctx->inode == NULL) {
Eprintf ("Error reading inode %lld.", ctx->mft_num);
return -1;
}
attr10 = find_first_attribute (AT_STANDARD_INFORMATION, ctx->inode->mrec);
attr20 = find_first_attribute (AT_ATTRIBUTE_LIST, ctx->inode->mrec);
attr80 = find_first_attribute (AT_DATA, ctx->inode->mrec);
if (attr10)
ctx->flags_match |= FEMR_BASE_RECORD;
else
ctx->flags_match |= FEMR_NOT_BASE_RECORD;
if (attr20)
ctx->flags_match |= FEMR_BASE_RECORD;
if (attr80)
ctx->flags_match |= FEMR_FILE;
if (ctx->flags_search & FEMR_DIR) {
attr_ctx = ntfs_attr_get_search_ctx (NULL, ctx->inode->mrec);
if (attr_ctx) {
if (ntfs_attr_lookup (AT_INDEX_ROOT, I30, 4, 0, 0, NULL, 0, attr_ctx) == 0)
ctx->flags_match |= FEMR_DIR;
ntfs_attr_put_search_ctx (attr_ctx);
} else {
Eprintf ("Couldn't create a search context.\n");
return -1;
}
}
switch (utils_is_metadata (ctx->inode)) {
case 1: ctx->flags_match |= FEMR_METADATA; break;
case 0: ctx->flags_match |= FEMR_NOT_METADATA; break;
default:
ctx->flags_match |= FEMR_NOT_METADATA; break;
//Eprintf ("Error reading inode %lld.", ctx->mft_num);
//return -1;
}
} else { // !in_use
ntfs_attr *mft;
ctx->flags_match |= FEMR_NOT_IN_USE;
ctx->inode = calloc (1, sizeof (*ctx->inode));
if (!ctx->inode) {
Eprintf ("Out of memory. Aborting.");
return -1;
}
ctx->inode->mft_no = ctx->mft_num;
ctx->inode->vol = ctx->vol;
ctx->inode->mrec = malloc (ctx->vol->mft_record_size);
if (!ctx->inode->mrec) {
free (ctx->inode); // == ntfs_inode_close
Eprintf ("Out of memory. Aborting.");
return -1;
}
mft = ntfs_attr_open (ctx->vol->mft_ni, AT_DATA, NULL, 0);
if (!mft) {
Eprintf ("Couldn't open $MFT/$DATA: %s\n", strerror (errno));
// free / close
return -1;
}
if (ntfs_attr_pread (mft, ctx->vol->mft_record_size * ctx->mft_num, ctx->vol->mft_record_size, ctx->inode->mrec) < ctx->vol->mft_record_size) {
Eprintf ("Couldn't read MFT Record %lld: %s.\n", ctx->mft_num, strerror (errno));
// free / close
return -1;
}
}
if (ctx->flags_match & ctx->flags_search) {
break;
}
if (ntfs_inode_close (ctx->inode)) {
Eprintf ("Error closing inode %lld.", ctx->mft_num);
return -errno;
}
ctx->inode = NULL;
}
return (ctx->inode == NULL);
}
#if 0
hamming weight
inline unsigned int hweight32(unsigned int w)

View File

@ -81,4 +81,33 @@ s64 utc2ntfs (time_t time);
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);
/**
* defines...
* if *not in use* then the other flags are ignored?
*/
#define FEMR_IN_USE 1 << 0
#define FEMR_NOT_IN_USE 1 << 1
#define FEMR_FILE 1 << 2 // $DATA
#define FEMR_DIR 1 << 3 // $INDEX_ROOT, "$I30"
#define FEMR_METADATA 1 << 4
#define FEMR_NOT_METADATA 1 << 5
#define FEMR_BASE_RECORD 1 << 6
#define FEMR_NOT_BASE_RECORD 1 << 7
#define FEMR_ALL_RECORDS 0xFF
/**
* struct mft_search_ctx
*/
struct mft_search_ctx {
int flags_search;
int flags_match;
ntfs_inode *inode;
u64 mft_num;
ntfs_volume *vol;
};
struct mft_search_ctx * mft_get_search_ctx (ntfs_volume *vol);
void mft_put_search_ctx (struct mft_search_ctx *ctx);
int mft_next_record (struct mft_search_ctx *ctx);
#endif /* _NTFS_UTILS_H_ */