- int (*capture_tree)(struct dentry **, const char *,
- struct lookup_table *,
- struct wim_security_data *,
- const struct capture_config *,
- int, wimlib_progress_func_t, void *);
- void *extra_arg;
-
- struct dentry *root_dentry = NULL;
- struct wim_security_data *sd;
- struct capture_config config;
- struct hlist_head inode_list;
- int ret;
-
- if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_NTFS) {
-#ifdef WITH_NTFS_3G
- if (add_image_flags & (WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE)) {
- ERROR("Cannot dereference files when capturing directly from NTFS");
- return WIMLIB_ERR_INVALID_PARAM;
- }
- capture_tree = build_dentry_tree_ntfs;
- extra_arg = &w->ntfs_vol;
-#else
- ERROR("wimlib was compiled without support for NTFS-3g, so\n"
- " cannot capture a WIM image directly from a NTFS volume!");
- return WIMLIB_ERR_UNSUPPORTED;
-#endif
- } else {
- capture_tree = build_dentry_tree;
- extra_arg = NULL;
- }
-
- DEBUG("Adding dentry tree from directory or NTFS volume `%s'.", source);
-
- if (!name || !*name) {
- ERROR("Must specify a non-empty string for the image name");
- return WIMLIB_ERR_INVALID_PARAM;
- }
- if (!source || !*source) {
- ERROR("Must specify the name of a directory or NTFS volume");
- return WIMLIB_ERR_INVALID_PARAM;
- }
-
- if (w->hdr.total_parts != 1) {
- ERROR("Cannot add an image to a split WIM");
- return WIMLIB_ERR_SPLIT_UNSUPPORTED;
- }
-
- if (wimlib_image_name_in_use(w, name)) {
- ERROR("There is already an image named \"%s\" in `%s'",
- name, w->filename);
- return WIMLIB_ERR_IMAGE_NAME_COLLISION;
- }
-
- DEBUG("Initializing capture configuration");
- if (!config_str) {
- DEBUG("Using default capture configuration");
- config_str = default_config;
- config_len = strlen(default_config);
- }
- ret = init_capture_config(config_str, config_len, source, &config);
- if (ret != 0)
- return ret;
- print_capture_config(&config);
-
- DEBUG("Allocating security data");
-
- sd = CALLOC(1, sizeof(struct wim_security_data));
- if (!sd) {
- ret = WIMLIB_ERR_NOMEM;
- goto out_destroy_config;
- }
- sd->total_length = 8;
- sd->refcnt = 1;
-
- if (progress_func) {
- union wimlib_progress_info progress;
- progress.scan.source = source;
- progress_func(WIMLIB_PROGRESS_MSG_SCAN_BEGIN, &progress);
- }
-
- DEBUG("Building dentry tree.");
- ret = (*capture_tree)(&root_dentry, source, w->lookup_table, sd,
- &config, add_image_flags | WIMLIB_ADD_IMAGE_FLAG_ROOT,
- progress_func, extra_arg);
- destroy_capture_config(&config);
-
- if (ret != 0) {
- ERROR("Failed to build dentry tree for `%s'", source);
- goto out_free_security_data;
- }
-
- if (progress_func) {
- union wimlib_progress_info progress;
- progress.scan.source = source;
- progress_func(WIMLIB_PROGRESS_MSG_SCAN_END, &progress);
- }
-
- DEBUG("Calculating full paths of dentries.");
- ret = for_dentry_in_tree(root_dentry, calculate_dentry_full_path, NULL);
- if (ret != 0)
- goto out_free_dentry_tree;
-
- ret = add_new_dentry_tree(w, root_dentry, sd);
- if (ret != 0)
- goto out_free_dentry_tree;
-
-
- ret = dentry_tree_fix_inodes(root_dentry, &inode_list);
- if (ret != 0)
- goto out_destroy_imd;
-
- DEBUG("Assigning hard link group IDs");
- assign_inode_numbers(&inode_list);
- w->image_metadata[w->hdr.image_count - 1].inode_list = inode_list;
-
- ret = xml_add_image(w, name);
- if (ret != 0)
- goto out_destroy_imd;
-
- if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_BOOT)
- wimlib_set_boot_idx(w, w->hdr.image_count);
- return 0;
-out_destroy_imd:
- destroy_image_metadata(&w->image_metadata[w->hdr.image_count - 1],
- w->lookup_table);
- w->hdr.image_count--;
- return ret;
-out_free_dentry_tree:
- free_dentry_tree(root_dentry, w->lookup_table);
-out_free_security_data:
- free_security_data(sd);
-out_destroy_config:
- destroy_capture_config(&config);
- return ret;