/** \internal * Copy the contents of one directory structure to another. * Note that this currently does not copy the FS_FILE info. * It is only used to make a copy of the orphan directory. * It does not check for duplicate entries. * @returns 1 on error */ static uint8_t tsk_fs_dir_copy(const TSK_FS_DIR * a_src_dir, TSK_FS_DIR * a_dst_dir) { size_t i; a_dst_dir->names_used = 0; // make sure we got the room if (a_src_dir->names_used > a_dst_dir->names_alloc) { if (tsk_fs_dir_realloc(a_dst_dir, a_src_dir->names_used)) return 1; } for (i = 0; i < a_src_dir->names_used; i++) { if (tsk_fs_name_copy(&a_dst_dir->names[i], &a_src_dir->names[i])) return 1; } a_dst_dir->names_used = a_src_dir->names_used; a_dst_dir->addr = a_src_dir->addr; return 0; }
/** \internal * Add a FS_DENT structure to a FS_DIR structure by copying its * contents into the internal buffer. Checks for * duplicates and expands buffer as needed. * @param a_fs_dir DIR to add to * @param a_fs_name DENT to add * @returns 1 on error (memory allocation problems) and 0 on success */ uint8_t tsk_fs_dir_add(TSK_FS_DIR * a_fs_dir, const TSK_FS_NAME * a_fs_name) { TSK_FS_NAME *fs_name_dest = NULL; size_t i; /* see if we already have it in the buffer / queue * We skip this check for FAT because it will always fail because two entries * never have the same meta address. */ // @@@ We could do something more effecient here too with orphan files because we do not // need to check the contents of that directory either and this takes a lot of time on those // large images. if (TSK_FS_TYPE_ISFAT(a_fs_dir->fs_info->ftype) == 0) { for (i = 0; i < a_fs_dir->names_used; i++) { if ((a_fs_name->meta_addr == a_fs_dir->names[i].meta_addr) && (strcmp(a_fs_name->name, a_fs_dir->names[i].name) == 0)) { if (tsk_verbose) tsk_fprintf(stderr, "tsk_fs_dir_add: removing duplicate entry: %s (%" PRIuINUM ")\n", a_fs_name->name, a_fs_name->meta_addr); /* We do not check type because then we cannot detect NTFS orphan file * duplicates that are added as "-/r" while a similar entry exists as "r/r" (a_fs_name->type == a_fs_dir->names[i].type)) { */ // if the one in the list is unalloc and we have an alloc, replace it if ((a_fs_dir->names[i].flags & TSK_FS_NAME_FLAG_UNALLOC) && (a_fs_name->flags & TSK_FS_NAME_FLAG_ALLOC)) { fs_name_dest = &a_fs_dir->names[i]; // free the memory - not the most effecient, but prevents // duplicate code. if (fs_name_dest->name) { free(fs_name_dest->name); fs_name_dest->name = NULL; fs_name_dest->name_size = 0; } if (fs_name_dest->shrt_name) { free(fs_name_dest->shrt_name); fs_name_dest->shrt_name = NULL; fs_name_dest->shrt_name_size = 0; } break; } else { return 0; } } } } if (fs_name_dest == NULL) { // make sure we got the room if (a_fs_dir->names_used >= a_fs_dir->names_alloc) { if (tsk_fs_dir_realloc(a_fs_dir, a_fs_dir->names_used + 512)) return 1; } fs_name_dest = &a_fs_dir->names[a_fs_dir->names_used++]; } if (tsk_fs_name_copy(fs_name_dest, a_fs_name)) return 1; // add the parent address if (a_fs_dir->addr) fs_name_dest->par_addr = a_fs_dir->addr; return 0; }
/** \internal * Add a FS_DENT structure to a FS_DIR structure by copying its * contents into the internal buffer. Checks for * duplicates and expands buffer as needed. * @param a_fs_dir DIR to add to * @param a_fs_name DENT to add * @returns 1 on error (memory allocation problems) and 0 on success */ uint8_t tsk_fs_dir_add(TSK_FS_DIR * a_fs_dir, const TSK_FS_NAME * a_fs_name) { TSK_FS_NAME *fs_name_dest = NULL; size_t i; // see if we already have it in the buffer / queue for (i = 0; i < a_fs_dir->names_used; i++) { if ((a_fs_name->meta_addr == a_fs_dir->names[i].meta_addr) && (strcmp(a_fs_name->name, a_fs_dir->names[i].name) == 0)) { if (tsk_verbose) tsk_fprintf(stderr, "tsk_fs_dir_add: removing duplicate entry: %s (%" PRIuINUM ")\n", a_fs_name->name, a_fs_name->meta_addr); /* We do not check type because then we cannot detect NTFS orphan file * duplicates that are added as "-/r" while a similar entry exists as "r/r" (a_fs_name->type == a_fs_dir->names[i].type)) { */ // if the one in the list is unalloc and we have an alloc, replace it if ((a_fs_dir->names[i].flags & TSK_FS_NAME_FLAG_UNALLOC) && (a_fs_name->flags & TSK_FS_NAME_FLAG_ALLOC)) { fs_name_dest = &a_fs_dir->names[i]; // free the memory - not the most effecient, but prevents // duplicate code. if (fs_name_dest->name) { free(fs_name_dest->name); fs_name_dest->name = NULL; fs_name_dest->name_size = 0; } if (fs_name_dest->shrt_name) { free(fs_name_dest->shrt_name); fs_name_dest->shrt_name = NULL; fs_name_dest->shrt_name_size = 0; } break; } else { return 0; } } } if (fs_name_dest == NULL) { // make sure we got the room if (a_fs_dir->names_used >= a_fs_dir->names_alloc) { if (tsk_fs_dir_realloc(a_fs_dir, a_fs_dir->names_used + 256)) return 1; } fs_name_dest = &a_fs_dir->names[a_fs_dir->names_used++]; } if (tsk_fs_name_copy(fs_name_dest, a_fs_name)) return 1; // add the parent address if (a_fs_dir->addr) fs_name_dest->par_addr = a_fs_dir->addr; return 0; }