/* Flags that affect the capture operation (WIMLIB_ADD_FLAG_*) */
int add_flags;
- /* If non-NULL, the user-supplied progress function. */
- wimlib_progress_func_t progress_func;
-
/* Extra argument; set to point to a pointer to the ntfs_volume for
* libntfs-3g capture. */
void *extra_arg;
u64 capture_root_ino;
u64 capture_root_dev;
+
+ /* If non-NULL, the user-supplied progress function. */
+ wimlib_progress_func_t progress_func;
+
+ /* Progress data. */
+ union wimlib_progress_info progress;
};
/* capture_common.c */
+extern void
+do_capture_progress(struct add_image_params *params, int status);
+
extern bool
exclude_path(const tchar *path, size_t path_len,
const struct wimlib_capture_config *config,
return false;
}
+void
+do_capture_progress(struct add_image_params *params, int status)
+{
+ switch (status) {
+ case WIMLIB_SCAN_DENTRY_OK:
+ if (!(params->add_flags & WIMLIB_ADD_FLAG_VERBOSE))
+ return;
+ case WIMLIB_SCAN_DENTRY_UNSUPPORTED:
+ case WIMLIB_SCAN_DENTRY_EXCLUDED:
+ if (!(params->add_flags & WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE))
+ return;
+ }
+ params->progress.scan.status = status;
+ if (params->progress_func) {
+ params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY,
+ ¶ms->progress);
+ }
+}
+
/* Return true if the image capture configuration file indicates we should
* exclude the filename @path from capture.
*
{
le32 attributes;
int ret;
- struct wim_dentry *root;
+ struct wim_dentry *root = NULL;
struct wim_inode *inode;
ATTR_TYPES stream_type;
+ params->progress.scan.cur_path = path;
+
if (exclude_path(path, path_len, params->config, false)) {
/* Exclude a file or directory tree based on the capture
* configuration file */
- if ((params->add_flags & WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE)
- && params->progress_func)
- {
- union wimlib_progress_info info;
- info.scan.cur_path = path;
- info.scan.status = WIMLIB_SCAN_DENTRY_EXCLUDED;
- params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY, &info);
- }
- root = NULL;
+ do_capture_progress(params, WIMLIB_SCAN_DENTRY_EXCLUDED);
ret = 0;
goto out;
}
ret = ntfs_get_ntfs_attrib(ni, (char*)&attributes, sizeof(attributes));
if (ret != sizeof(attributes)) {
ERROR_WITH_ERRNO("Failed to get NTFS attributes from \"%s\"", path);
- return WIMLIB_ERR_NTFS_3G;
+ ret = WIMLIB_ERR_NTFS_3G;
+ goto out;
}
if ((attributes & (FILE_ATTRIBUTE_DIRECTORY |
if (params->add_flags & WIMLIB_ADD_FLAG_NO_UNSUPPORTED_EXCLUDE)
{
ERROR("Can't archive unsupported encrypted file \"%s\"", path);
- return WIMLIB_ERR_UNSUPPORTED_FILE;
- }
- if ((params->add_flags & WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE)
- && params->progress_func)
- {
- union wimlib_progress_info info;
- info.scan.cur_path = path;
- info.scan.status = WIMLIB_SCAN_DENTRY_UNSUPPORTED;
- params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY, &info);
+ ret = WIMLIB_ERR_UNSUPPORTED_FILE;
+ goto out;
}
- root = NULL;
+ do_capture_progress(params, WIMLIB_SCAN_DENTRY_UNSUPPORTED);
ret = 0;
goto out;
}
- if ((params->add_flags & WIMLIB_ADD_FLAG_VERBOSE)
- && params->progress_func)
- {
- union wimlib_progress_info info;
- info.scan.cur_path = path;
- info.scan.status = WIMLIB_SCAN_DENTRY_OK;
- params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY, &info);
- }
+ do_capture_progress(params, WIMLIB_SCAN_DENTRY_OK);
/* Create a WIM dentry with an associated inode, which may be shared */
ret = inode_table_new_dentry(¶ms->inode_table,
path_basename_with_len(path, path_len),
ni->mft_no, 0, false, &root);
if (ret)
- return ret;
+ goto out;
if (name_type & FILE_NAME_WIN32) /* Win32 or Win32+DOS name (rather than POSIX) */
root->is_win32_name = 1;
inode = root->d_inode;
- if (inode->i_nlink > 1) /* Shared inode; nothing more to do */
+ if (inode->i_nlink > 1) {
+ /* Shared inode; nothing more to do */
+ ret = 0;
goto out;
+ }
inode->i_creation_time = le64_to_cpu(ni->creation_time);
inode->i_last_write_time = le64_to_cpu(ni->last_data_change_time);
struct add_image_params *params)
{
struct wim_dentry *root = NULL;
- int ret = 0;
+ int ret;
struct wim_inode *inode;
+ params->progress.scan.cur_path = path;
+
if (exclude_path(path, path_len, params->config, true)) {
- if ((params->add_flags & WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE)
- && params->progress_func)
- {
- union wimlib_progress_info info;
- info.scan.cur_path = path;
- info.scan.status = WIMLIB_SCAN_DENTRY_EXCLUDED;
- params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY, &info);
- }
+ do_capture_progress(params, WIMLIB_SCAN_DENTRY_EXCLUDED);
+ ret = 0;
goto out;
}
- if ((params->add_flags & WIMLIB_ADD_FLAG_VERBOSE)
- && params->progress_func)
- {
- union wimlib_progress_info info;
- info.scan.cur_path = path;
- info.scan.status = WIMLIB_SCAN_DENTRY_OK;
- params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY, &info);
- }
-
struct stat stbuf;
int (*stat_fn)(const char *restrict, struct stat *restrict);
if ((params->add_flags & WIMLIB_ADD_FLAG_DEREFERENCE) ||
if (params->add_flags & WIMLIB_ADD_FLAG_NO_UNSUPPORTED_EXCLUDE)
{
ERROR("Can't archive unsupported file \"%s\"", path);
- return WIMLIB_ERR_UNSUPPORTED_FILE;
- }
- if ((params->add_flags & WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE)
- && params->progress_func)
- {
- union wimlib_progress_info info;
- info.scan.cur_path = path;
- info.scan.status = WIMLIB_SCAN_DENTRY_UNSUPPORTED;
- params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY, &info);
+ ret = WIMLIB_ERR_UNSUPPORTED_FILE;
+ goto out;
}
+ do_capture_progress(params, WIMLIB_SCAN_DENTRY_UNSUPPORTED);
+ ret = 0;
goto out;
}
+ do_capture_progress(params, WIMLIB_SCAN_DENTRY_OK);
+
ret = inode_table_new_dentry(¶ms->inode_table,
path_basename_with_len(path, path_len),
stbuf.st_ino, stbuf.st_dev, false, &root);
inode = root->d_inode;
- if (inode->i_nlink > 1) /* Already captured this inode? */
+ if (inode->i_nlink > 1) {
+ /* Already captured this inode? */
+ ret = 0;
goto out;
+ }
#ifdef HAVE_STAT_NANOSECOND_PRECISION
inode->i_creation_time = timespec_to_wim_timestamp(stbuf.st_mtim);
ret = unix_capture_directory(root, path, path_len, params);
else
ret = unix_capture_symlink(&root, path, inode, params);
+
+ if (ret)
+ goto out;
+
out:
- if (ret == 0)
- *root_ret = root;
- else
+ if (ret)
free_dentry_tree(root, params->lookup_table);
+ else
+ *root_ret = root;
return ret;
}
int (*capture_tree)(struct wim_dentry **,
const tchar *,
struct add_image_params *);
- union wimlib_progress_info progress;
struct wimlib_capture_config *config;
#ifdef WITH_NTFS_3G
struct _ntfs_volume *ntfs_vol = NULL;
bool rollback_sd = true;
wimlib_assert(add_cmd->op == WIMLIB_UPDATE_OP_ADD);
+
add_flags = add_cmd->add.add_flags;
fs_source_path = add_cmd->add.fs_source_path;
wim_target_path = add_cmd->add.wim_target_path;
DEBUG("fs_source_path=\"%"TS"\", wim_target_path=\"%"TS"\", add_flags=%#x",
fs_source_path, wim_target_path, add_flags);
+ memset(¶ms, 0, sizeof(params));
+
imd = wim->image_metadata[wim->current_image - 1];
if (add_flags & WIMLIB_ADD_FLAG_NTFS) {
extra_arg = NULL;
}
+
ret = init_inode_table(¶ms.inode_table, 9001);
if (ret)
goto out;
params.lookup_table = wim->lookup_table;
params.config = config;
params.add_flags = add_flags;
- params.progress_func = progress_func;
params.extra_arg = extra_arg;
- if (progress_func) {
- memset(&progress, 0, sizeof(progress));
- progress.scan.source = fs_source_path;
- progress.scan.wim_target_path = wim_target_path;
- progress_func(WIMLIB_PROGRESS_MSG_SCAN_BEGIN, &progress);
- }
+ params.progress_func = progress_func;
+ params.progress.scan.source = fs_source_path;
+ params.progress.scan.wim_target_path = wim_target_path;
+ if (progress_func)
+ progress_func(WIMLIB_PROGRESS_MSG_SCAN_BEGIN, ¶ms.progress);
if (config) {
config->_prefix = fs_source_path;
config->_prefix_num_tchars = tstrlen(fs_source_path);
goto out_ntfs_umount;
}
if (progress_func)
- progress_func(WIMLIB_PROGRESS_MSG_SCAN_END, &progress);
+ progress_func(WIMLIB_PROGRESS_MSG_SCAN_END, ¶ms.progress);
list_splice_tail(&unhashed_streams, &imd->unhashed_streams);
#ifdef WITH_NTFS_3G
imd->ntfs_vol = ntfs_vol;
u16 rpbuflen;
u16 not_rpfixed;
+ params->progress.scan.cur_path = path;
+
if (exclude_path(path, path_num_chars, params->config, true)) {
if (params->add_flags & WIMLIB_ADD_FLAG_ROOT) {
ERROR("Cannot exclude the root directory from capture");
ret = WIMLIB_ERR_INVALID_CAPTURE_CONFIG;
goto out;
}
- if ((params->add_flags & WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE)
- && params->progress_func)
- {
- union wimlib_progress_info info;
- info.scan.cur_path = path;
- info.scan.status = WIMLIB_SCAN_DENTRY_EXCLUDED;
- params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY, &info);
- }
+ do_capture_progress(params, WIMLIB_SCAN_DENTRY_EXCLUDED);
ret = 0;
goto out;
}
}
#endif
- if ((params->add_flags & WIMLIB_ADD_FLAG_VERBOSE)
- && params->progress_func)
- {
- union wimlib_progress_info info;
- info.scan.cur_path = path;
- info.scan.status = WIMLIB_SCAN_DENTRY_OK;
- params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY, &info);
- }
+ do_capture_progress(params, WIMLIB_SCAN_DENTRY_OK);
HANDLE hFile = win32_open_existing_file(path,
FILE_READ_DATA | FILE_READ_ATTRIBUTES);