include/wimlib/metadata.h \
include/wimlib/pathlist.h \
include/wimlib/paths.h \
+ include/wimlib/progress.h \
include/wimlib/reparse.h \
include/wimlib/resource.h \
include/wimlib/security.h \
WIMLIB_COMPRESSION_TYPE_LZX is now 2 (so it's the same as
WIMGAPI).
+ - Progress functions, including their prototypes as well as how
+ they are provided to the library, have been changed.
+
- 'struct wimlib_capture_config' has been removed. The library
now takes the path to the configuration file directly. This
affects wimlib_add_image(), wimlib_add_image_multisource(),
#define TO_PERCENT(numerator, denominator) \
((float)(((denominator) == 0) ? 0 : ((numerator) * 100 / (float)(denominator))))
-static int
+static enum wimlib_progress_status
extract_progress(enum wimlib_progress_msg msg,
- const union wimlib_progress_info *info)
+ union wimlib_progress_info *info, void *progctx)
{
switch (msg) {
case WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS:
default:
break;
}
- return 0;
+ return WIMLIB_PROGRESS_STATUS_CONTINUE;
}
int main(int argc, char **argv)
/* Open the WIM file as a WIMStruct. */
ret = wimlib_open_wim(wimpath, /* Path of WIM file to open */
0, /* WIMLIB_OPEN_FLAG_* flags (0 means all defaults) */
- &wim, /* Return the WIMStruct pointer in this location */
- NULL); /* Progress function (NULL means none) */
+ &wim); /* Return the WIMStruct pointer in this location */
if (ret != 0) /* Always should check the error codes. */
goto out;
+ /* Register our progress function. */
+ wimlib_register_progress_function(wim, extract_progress, NULL);
+
/* Extract the first image. */
ret = wimlib_extract_image(wim, /* WIMStruct from which to extract the image */
1, /* Image to extract */
destdir, /* Directory to extract the image to */
- 0, /* WIMLIB_EXTRACT_FLAG_* flags (0 means all defaults) */
- extract_progress); /* Progress function */
+ 0); /* WIMLIB_EXTRACT_FLAG_* flags (0 means all defaults) */
out:
/* Free the WIMStruct. Has no effect if the pointer to it is NULL. */
#define TO_PERCENT(numerator, denominator) \
((float)(((denominator) == 0) ? 0 : ((numerator) * 100 / (float)(denominator))))
-static int
+static enum wimlib_progress_status
write_progress(enum wimlib_progress_msg msg,
- const union wimlib_progress_info *info)
+ union wimlib_progress_info *info, void *progctx)
{
switch (msg) {
case WIMLIB_PROGRESS_MSG_WRITE_STREAMS:
default:
break;
}
- return 0;
+ return WIMLIB_PROGRESS_STATUS_CONTINUE;
}
int main(int argc, char **argv)
if (ret != 0) /* Always should check the error codes. */
goto out;
+ /* Register our progress function. */
+ wimlib_register_progress_function(wim, write_progress, NULL);
+
/* Add the directory tree to the WIMStruct as an image. */
ret = wimlib_add_image(wim, /* WIMStruct to which to add the image */
srcdir, /* Directory from which to add the image */
NULL, /* Name to give the image (NULL means none) */
NULL, /* Capture configuration structure (NULL means none) */
- 0, /* WIMLIB_ADD_FLAG_* flags (0 means all defaults) */
- NULL); /* Progress function (NULL means none) */
+ 0); /* WIMLIB_ADD_FLAG_* flags (0 means all defaults) */
if (ret != 0)
goto out;
wimpath, /* Path to write the WIM to */
WIMLIB_ALL_IMAGES, /* Image(s) in the WIM to write */
0, /* WIMLIB_WRITE_FLAG_* flags (0 means all defaults) */
- 0, /* Number of compressor threads (0 means default) */
- write_progress); /* Progress function */
+ 0); /* Number of compressor threads (0 means default) */
out:
/* Free the WIMStruct. Has no effect if the pointer to it is NULL. */
* image read-write is an alternative to calling wimlib_update_image().
*/
-/** @defgroup G_progress Progress Messages
+/**
+ * @defgroup G_progress Progress Messages
*
* @brief Track the progress of long WIM operations.
*
- * When operating on large archives, operations such as extraction will
- * naturally take a while to complete. Because of this and to improve the
- * potential user-friendliness of library clients, a number of functions take a
- * pointer to a progress function of type ::wimlib_progress_func_t. This
- * function will be called periodically during the WIM operation(s) to report on
- * the progress of the operation (for example, how many bytes have been written
- * so far).
+ * Library users can provide a progress function which will be called
+ * periodically during operations such as extracting a WIM image or writing a
+ * WIM image. A ::WIMStruct can have a progress function of type
+ * ::wimlib_progress_func_t associated with it by calling
+ * wimlib_register_progress_function() or by opening the ::WIMStruct using
+ * wimlib_open_wim_with_progress(). Once this is done, the progress function
+ * will be called automatically during many operations, such as
+ * wimlib_extract_image() and wimlib_write().
+ *
+ * Some functions that do not operate directly on a user-provided ::WIMStruct,
+ * such as wimlib_join(), also take the progress function directly using an
+ * extended version of the function, such as wimlib_join_with_progress().
+ *
+ * In wimlib v1.6.3 and later, progress functions are no longer just
+ * unidirectional. You can now return ::WIMLIB_PROGRESS_STATUS_ABORT to cause
+ * the current operation to be aborted. wimlib v1.6.3 also added the third
+ * argument to ::wimlib_progress_func_t, which is a user-supplied context.
*/
/** @defgroup G_writing_and_overwriting_wims Writing and Overwriting WIMs
/** The contents of the WIM file are being checked against the integrity
* table. @p info will point to ::wimlib_progress_info.integrity. This
* message is only received (and may be received many times) when
- * wimlib_open_wim() is called with the
+ * wimlib_open_wim_with_progress() is called with the
* ::WIMLIB_OPEN_FLAG_CHECK_INTEGRITY flag. */
WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY = 16,
WIMLIB_PROGRESS_MSG_WIMBOOT_EXCLUDE = 24,
};
+/** Valid return values from user-provided progress functions
+ * (::wimlib_progress_func_t).
+ *
+ * (Note: if an invalid value is returned, ::WIMLIB_ERR_UNKNOWN_PROGRESS_STATUS
+ * will be issued.)
+ */
+enum wimlib_progress_status {
+
+ /** The operation should be continued. This is the normal return value.
+ */
+ WIMLIB_PROGRESS_STATUS_CONTINUE = 0,
+
+ /** The operation should be aborted. This will cause the current
+ * operation to fail with ::WIMLIB_ERR_ABORTED_BY_PROGRESS. */
+ WIMLIB_PROGRESS_STATUS_ABORT = 1,
+};
+
/** A pointer to this union is passed to the user-supplied
* ::wimlib_progress_func_t progress function. One (or none) of the structures
* contained in this union will be applicable for the operation
} wimboot_exclude;
};
-/** A user-supplied function that will be called periodically during certain WIM
- * operations. The first argument will be the type of operation that is being
- * performed or is about to be started or has been completed. The second
- * argument will be a pointer to one of a number of structures depending on the
- * first argument. It may be @c NULL for some message types.
+/**
+ * A user-supplied function that will be called periodically during certain WIM
+ * operations.
+ *
+ * The first argument will be the type of operation that is being performed or
+ * is about to be started or has been completed.
+ *
+ * The second argument will be a pointer to one of a number of structures
+ * depending on the first argument. It may be @c NULL for some message types.
+ * Note that although this argument is not @c const, users should not modify it
+ * except in explicitly documented cases.
*
- * The return value of the progress function is currently ignored, but it may do
- * something in the future. (Set it to 0 for now.)
+ * The third argument will be a user-supplied value that was provided when
+ * registering or specifying the progress function.
+ *
+ * This function must return one of the ::wimlib_progress_status values. By
+ * default, you should return ::WIMLIB_PROGRESS_STATUS_CONTINUE (0).
*/
-typedef int (*wimlib_progress_func_t)(enum wimlib_progress_msg msg_type,
- const union wimlib_progress_info *info);
+typedef enum wimlib_progress_status
+ (*wimlib_progress_func_t)(enum wimlib_progress_msg msg_type,
+ union wimlib_progress_info *info,
+ void *progctx);
/** @} */
/** @ingroup G_modifying_wims
WIMLIB_ERR_XML,
WIMLIB_ERR_WIM_IS_ENCRYPTED,
WIMLIB_ERR_WIMBOOT,
+ WIMLIB_ERR_ABORTED_BY_PROGRESS,
+ WIMLIB_ERR_UNKNOWN_PROGRESS_STATUS,
};
* ::WIMLIB_ADD_FLAG_WIMBOOT flags modify the default.
* @param add_flags
* Bitwise OR of flags prefixed with WIMLIB_ADD_FLAG.
- * @param progress_func
- * If non-NULL, a function that will be called periodically with the
- * progress of the current operation. The progress messages that will be
- * received are ::WIMLIB_PROGRESS_MSG_SCAN_BEGIN,
- * ::WIMLIB_PROGRESS_MSG_SCAN_END, and, if ::WIMLIB_ADD_FLAG_VERBOSE was
- * included in @p add_flags, also ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY.
*
* @return 0 on success; nonzero on error. On error, changes to @p wim are
* discarded so that it appears to be in the same state as when this function
* returned by wimlib_add_empty_image() may be returned, as well as any error
* codes returned by wimlib_update_image() other than ones documented as only
* being returned specifically by an update involving delete or rename commands.
+ *
+ * If a progress function is registered with @p wim, it will receive the
+ * messages ::WIMLIB_PROGRESS_MSG_SCAN_BEGIN and ::WIMLIB_PROGRESS_MSG_SCAN_END.
+ * In addition, if ::WIMLIB_ADD_FLAG_VERBOSE is specified in @p add_flags, it
+ * will receive ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY.
*/
extern int
wimlib_add_image(WIMStruct *wim,
const wimlib_tchar *source,
const wimlib_tchar *name,
const wimlib_tchar *config_file,
- int add_flags,
- wimlib_progress_func_t progress_func);
+ int add_flags);
/**
* @ingroup G_modifying_wims
size_t num_sources,
const wimlib_tchar *name,
const wimlib_tchar *config_file,
- int add_flags,
- wimlib_progress_func_t progress_func);
+ int add_flags);
/**
* @ingroup G_modifying_wims
* parameter is overridden by ::WIMLIB_EXPORT_FLAG_NO_DESCRIPTIONS.
* @param export_flags
* Bitwise OR of flags prefixed with WIMLIB_EXPORT_FLAG.
- * @param progress_func
- * Currently ignored, but reserved for a function that will be called with
- * information about the operation. Use NULL if no additional information
- * is desired.
*
* @return 0 on success; nonzero on error.
* @retval ::WIMLIB_ERR_IMAGE_NAME_COLLISION
WIMStruct *dest_wim,
const wimlib_tchar *dest_name,
const wimlib_tchar *dest_description,
- int export_flags,
- wimlib_progress_func_t progress_func);
-
+ int export_flags);
/**
* @ingroup G_extracting_wims
* the unmounted NTFS volume to which to extract the image.
* @param extract_flags
* Bitwise OR of flags prefixed with WIMLIB_EXTRACT_FLAG.
- * @param progress_func
- * If non-NULL, a function that will be called periodically with the
- * progress of the current operation. The main message to look for is
- * ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS; however, there are others as
- * well.
*
* @return 0 on success; nonzero on error.
* @retval ::WIMLIB_ERR_DECOMPRESSION
* there was a problem creating WIMBoot pointer files.
* @retval ::WIMLIB_ERR_WRITE
* Failed to write data to a file being extracted.
+ *
+ * If a progress function is registered with @p wim, then as each image is
+ * extracted it will receive ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN, then
+ * zero or more ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS messages, then
+ * ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END.
*/
extern int
wimlib_extract_image(WIMStruct *wim, int image,
- const wimlib_tchar *target,
- int extract_flags,
- wimlib_progress_func_t progress_func);
+ const wimlib_tchar *target, int extract_flags);
/**
* @ingroup G_extracting_wims
* Same as the corresponding parameter to wimlib_extract_image().
* @param extract_flags
* Same as the corresponding parameter to wimlib_extract_image().
- * @param progress_func
- * Same as the corresponding parameter to wimlib_extract_image(), except
- * ::WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN messages will also be
- * received by the progress function.
*
* @return 0 on success; nonzero on error. The possible error codes include
* those returned by wimlib_extract_image() and wimlib_open_wim() as well as the
extern int
wimlib_extract_image_from_pipe(int pipe_fd,
const wimlib_tchar *image_num_or_name,
- const wimlib_tchar *target, int extract_flags,
- wimlib_progress_func_t progress_func);
+ const wimlib_tchar *target, int extract_flags);
+
+/*
+ * @ingroup G_extracting_wims
+ *
+ * Same as wimlib_extract_image_from_pipe(), but allows specifying a progress
+ * function. The progress function will be used while extracting the WIM image
+ * and will receive the normal extraction progress messages, such as
+ * ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS, in addition to
+ * ::WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN.
+ */
+extern int
+wimlib_extract_image_from_pipe_with_progress(int pipe_fd,
+ const wimlib_tchar *image_num_or_name,
+ const wimlib_tchar *target,
+ int extract_flags,
+ wimlib_progress_func_t progfunc,
+ void *progctx);
/**
* @ingroup G_extracting_wims
wimlib_extract_pathlist(WIMStruct *wim, int image,
const wimlib_tchar *target,
const wimlib_tchar *path_list_file,
- int extract_flags,
- wimlib_progress_func_t progress_func);
+ int extract_flags);
/**
* @ingroup G_extracting_wims
* systems it may not contain backslashes, for example.
* @param extract_flags
* Bitwise OR of flags prefixed with WIMLIB_EXTRACT_FLAG.
- * @param progress_func
- * If non-NULL, a function that will be called periodically with the
- * progress of the current operation. The main message to look for is
- * ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS; however, there are others as
- * well. Note: because the extraction code is stream-based and not
- * file-based, there is no way to get information about which path is
- * currently being extracted, but based on byte count you can still
- * calculate an approximate percentage complete for the extraction overall
- * which may be all you really need anyway.
*
* @return 0 on success; nonzero on error. Most of the error codes are the same
* as those returned by wimlib_extract_image(). Below, some of the error codes
* @retval ::WIMLIB_ERR_NOT_A_REGULAR_FILE
* ::WIMLIB_EXTRACT_FLAG_TO_STDOUT was specified in @p extract_flags, but
* one of the paths to extract did not name a regular file.
+ *
+ * If a progress function is registered with @p wim, it will receive
+ * ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS. Note that because the extraction code
+ * is stream-based and not file-based, there is no way to get information about
+ * which path is currently being extracted, but based on byte count you can
+ * still calculate an approximate percentage complete for the extraction overall
+ * which may be all you really need anyway.
*/
extern int
wimlib_extract_paths(WIMStruct *wim,
const wimlib_tchar *target,
const wimlib_tchar * const *paths,
size_t num_paths,
- int extract_flags,
- wimlib_progress_func_t progress_func);
+ int extract_flags);
/**
* @ingroup G_wim_information
* be used to write the joined WIM.
* @param output_path
* The path to write the joined WIM file to.
- * @param progress_func
- * If non-NULL, a function that will be called periodically with the
- * progress of the current operation.
*
* @return 0 on success; nonzero on error. This function may return most error
* codes that can be returned by wimlib_open_wim() and wimlib_write(), as well
unsigned num_swms,
const wimlib_tchar *output_path,
int swm_open_flags,
- int wim_write_flags,
- wimlib_progress_func_t progress_func);
+ int wim_write_flags);
+
+/**
+ * @ingroup G_nonstandalone_wims
+ *
+ * Same as wimlib_join(), but allows specifying a progress function. The
+ * progress function will receive the write progress messages, such as
+ * ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS, while writing the joined WIM. In
+ * addition, if ::WIMLIB_OPEN_FLAG_CHECK_INTEGRITY is specified in @p
+ * swm_open_flags, the progress function will receive a series of
+ * ::WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY messages when each of the split WIM
+ * parts is opened.
+ */
+extern int
+wimlib_join_with_progress(const wimlib_tchar * const *swms,
+ unsigned num_swms,
+ const wimlib_tchar *output_path,
+ int swm_open_flags,
+ int wim_write_flags,
+ wimlib_progress_func_t progfunc,
+ void *progctx);
/**
* @param open_flags
* Bitwise OR of flags prefixed with WIMLIB_OPEN_FLAG.
*
- * @param progress_func
- * If non-NULL, a function that will be called periodically with the
- * progress of the current operation. Currently, the only messages sent
- * will be ::WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY, and only if
- * ::WIMLIB_OPEN_FLAG_CHECK_INTEGRITY was specified in @p open_flags.
- *
* @param wim_ret
* On success, a pointer to an opaque ::WIMStruct for the opened WIM file
* is written to the memory location pointed to by this parameter. The
extern int
wimlib_open_wim(const wimlib_tchar *wim_file,
int open_flags,
- WIMStruct **wim_ret,
- wimlib_progress_func_t progress_func);
+ WIMStruct **wim_ret);
+
+/**
+ * @ingroup G_creating_and_opening_wims
+ *
+ * Same as wimlib_open_wim(), but allows specifying a progress function and
+ * progress context. If successful, the progress function will be registered in
+ * the newly open ::WIMStruct. In addition, if
+ * ::WIMLIB_OPEN_FLAG_CHECK_INTEGRITY is specified in @p open_flags, the
+ * progress function will receive ::WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY
+ * messages while checking the WIM's integrity.
+ */
+extern int
+wimlib_open_wim_with_progress(const wimlib_tchar *wim_file,
+ int open_flags,
+ WIMStruct **wim_ret,
+ wimlib_progress_func_t progfunc,
+ void *progctx);
/**
* @ingroup G_writing_and_overwriting_wims
* Bitwise OR of relevant flags prefixed with WIMLIB_WRITE_FLAG.
* @param num_threads
* Number of threads to use for compression (see wimlib_write()).
- * @param progress_func
- * If non-NULL, a function that will be called periodically with the
- * progress of the current operation.
*
* @return 0 on success; nonzero on error. This function may return most error
* codes returned by wimlib_write() as well as the following error codes:
* The WIM file is considered read-only because of any of the reasons
* mentioned in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS
* flag.
+ *
+ * If a progress function is registered with @p wim, it will receive the
+ * messages ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS,
+ * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_BEGIN, and
+ * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_END.
*/
extern int
-wimlib_overwrite(WIMStruct *wim, int write_flags, unsigned num_threads,
- wimlib_progress_func_t progress_func);
+wimlib_overwrite(WIMStruct *wim, int write_flags, unsigned num_threads);
/**
* @ingroup G_wim_information
* @param open_flags
* Additional open flags, such as ::WIMLIB_OPEN_FLAG_CHECK_INTEGRITY, to
* pass to internal calls to wimlib_open_wim() on the reference files.
- * @param progress_func
- * Passed to internal calls to wimlib_open_wim() on the reference files.
*
* @return 0 on success; nonzero on error.
*
const wimlib_tchar * const *resource_wimfiles_or_globs,
unsigned count,
int ref_flags,
- int open_flags,
- wimlib_progress_func_t progress_func);
+ int open_flags);
/**
* @ingroup G_nonstandalone_wims
* of the directory tree being captured.
* @param flags
* Reserved; must be 0.
- * @param progress_func
- * Currently ignored, but reserved for a function that will be called with
- * information about the operation. Use NULL if no additional information
- * is desired.
*
* @return 0 on success; nonzero on error.
*
extern int
wimlib_reference_template_image(WIMStruct *wim, int new_image,
WIMStruct *template_wim, int template_image,
- int flags, wimlib_progress_func_t progress_func);
+ int flags);
+
+/**
+ * @ingroup G_general
+ *
+ * Registers a progress function with a ::WIMStruct.
+ *
+ * @param wim
+ * The ::WIMStruct for which to register the progress function.
+ * @param progfunc
+ * Pointer to the progress function to register. If the WIM already has a
+ * progress function registered, it will be replaced with this one. If @p
+ * NULL, the current progress function (if any) will be unregistered.
+ * @param progctx
+ * The value which will be passed as the third argument to calls to @p
+ * progfunc.
+ */
+extern void
+wimlib_register_progress_function(WIMStruct *wim,
+ wimlib_progress_func_t progfunc,
+ void *progctx);
/**
* @ingroup G_modifying_wims
* Bitwise OR of relevant flags prefixed with @c WIMLIB_WRITE_FLAG. These
* flags will be used to write each split WIM part. Specify 0 here to get
* the default behavior.
- * @param progress_func
- * If non-NULL, a function that will be called periodically with the
- * progress of the current operation
- * (::WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART and
- * ::WIMLIB_PROGRESS_MSG_SPLIT_END_PART).
*
* @return 0 on success; nonzero on error. This function may return most error
* codes that can be returned by wimlib_write() as well as the following error
* when they are copied from the joined WIM to the split WIM parts, nor are
* compressed resources re-compressed (unless explicitly requested with
* ::WIMLIB_WRITE_FLAG_RECOMPRESS).
+ *
+ * If a progress function is registered with @p wim, for each split WIM part
+ * that is written it will receive the messages
+ * ::WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART and
+ * ::WIMLIB_PROGRESS_MSG_SPLIT_END_PART.
*/
extern int
wimlib_split(WIMStruct *wim,
const wimlib_tchar *swm_name,
uint64_t part_size,
- int write_flags,
- wimlib_progress_func_t progress_func);
+ int write_flags);
/**
* @ingroup G_mounting_wim_images
* ::WIMLIB_UNMOUNT_FLAG_COMMIT, ::WIMLIB_UNMOUNT_FLAG_REBUILD, and/or
* ::WIMLIB_UNMOUNT_FLAG_RECOMPRESS. None of these flags affect read-only
* mounts.
- * @param progress_func
- * If non-NULL, a function that will be called periodically with the
- * progress of the current operation. Currently, only
- * ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS will be sent.
*
* @return 0 on success; nonzero on error.
*
*/
extern int
wimlib_unmount_image(const wimlib_tchar *dir,
- int unmount_flags,
- wimlib_progress_func_t progress_func);
+ int unmount_flags);
+
+/**
+ * @ingroup G_mounting_wim_images
+ *
+ * Same as wimlib_unmount_image(), but allows specifying a progress function.
+ * If changes are committed from a read-write mount, the progress function will
+ * receive ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS messages.
+ */
+extern int
+wimlib_unmount_image_with_progress(const wimlib_tchar *dir,
+ int unmount_flags,
+ wimlib_progress_func_t progfunc,
+ void *progctx);
/**
* @ingroup G_modifying_wims
* Number of commands in @p cmds.
* @param update_flags
* ::WIMLIB_UPDATE_FLAG_SEND_PROGRESS or 0.
- * @param progress_func
- * If non-NULL, a function that will be called periodically with the
- * progress of the current operation.
*
* @return 0 on success; nonzero on error. On failure, all update commands will
* be rolled back, and no visible changes shall have been made to @p wim.
int image,
const struct wimlib_update_command *cmds,
size_t num_cmds,
- int update_flags,
- wimlib_progress_func_t progress_func);
+ int update_flags);
/**
* @ingroup G_writing_and_overwriting_wims
* exporting an image from a compressed WIM to another WIM of the same
* compression type without ::WIMLIB_WRITE_FLAG_RECOMPRESS specified in @p
* write_flags).
- * @param progress_func
- * If non-NULL, a function that will be called periodically with the
- * progress of the current operation. The possible messages are
- * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_BEGIN,
- * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_END, and
- * ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS.
*
* @return 0 on success; nonzero on error.
*
* ::WIMLIB_ERR_UNEXPECTED_END_OF_FILE, all of which indicate failure (for
* different reasons) to read the metadata resource for an image that needed to
* be written.
+ *
+ * If a progress function is registered with @p wim, it will receive the
+ * messages ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS,
+ * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_BEGIN, and
+ * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_END.
*/
extern int
wimlib_write(WIMStruct *wim,
const wimlib_tchar *path,
int image,
int write_flags,
- unsigned num_threads,
- wimlib_progress_func_t progress_func);
+ unsigned num_threads);
/**
* @ingroup G_writing_and_overwriting_wims
int fd,
int image,
int write_flags,
- unsigned num_threads,
- wimlib_progress_func_t progress_func);
+ unsigned num_threads);
/**
* @defgroup G_compression Compression and decompression functions
#define _WIMLIB_APPLY_H
#include "wimlib/list.h"
+#include "wimlib/progress.h"
#include "wimlib/types.h"
#include "wimlib.h"
int extract_flags;
/* User-provided progress function, or NULL if not specified. */
- wimlib_progress_func_t progress_func;
+ wimlib_progress_func_t progfunc;
+ void *progctx;
/* Progress data buffer, with progress.extract initialized. */
union wimlib_progress_info progress;
struct wim_lookup_table_entry *cur_stream;
};
+static inline int
+extract_progress(struct apply_ctx *ctx, enum wimlib_progress_msg msg)
+{
+ return call_progress(ctx->progfunc, msg, &ctx->progress, ctx->progctx);
+}
+
/* Returns any of the aliases of an inode that are being extracted. */
#define inode_first_extraction_dentry(inode) \
list_first_entry(&(inode)->i_extraction_aliases, \
* libntfs-3g capture. */
void *extra_arg;
-
/* If non-NULL, the user-supplied progress function. */
- wimlib_progress_func_t progress_func;
+ wimlib_progress_func_t progfunc;
+ void *progctx;
/* Progress data. */
union wimlib_progress_info progress;
size_t capture_root_nchars;
};
-
/* capture_common.c */
-extern void
+extern int
do_capture_progress(struct add_image_params *params, int status,
const struct wim_inode *inode);
#ifndef _WIMLIB_INTEGRITY_H
#define _WIMLIB_INTEGRITY_H
-#include "wimlib.h"
+#include "wimlib/types.h"
#include <sys/types.h>
#define WIM_INTEGRITY_OK 0
extern int
write_integrity_table(WIMStruct *wim,
off_t new_lookup_table_end,
- off_t old_lookup_table_end,
- wimlib_progress_func_t progress_func);
+ off_t old_lookup_table_end);
extern int
-check_wim_integrity(WIMStruct *wim, wimlib_progress_func_t progress_func);
+check_wim_integrity(WIMStruct *wim);
#endif /* _WIMLIB_INTEGRITY_H */
--- /dev/null
+#ifndef _WIMLIB_PROGRESS_H
+#define _WIMLIB_PROGRESS_H
+
+#include "wimlib.h"
+
+/* If specified, call the user-provided progress function and check its result.
+ */
+static inline int
+call_progress(wimlib_progress_func_t progfunc,
+ enum wimlib_progress_msg msg,
+ union wimlib_progress_info *info,
+ void *progctx)
+{
+ if (progfunc) {
+ enum wimlib_progress_status status;
+
+ status = (*progfunc)(msg, info, progctx);
+
+ switch (status) {
+ case WIMLIB_PROGRESS_STATUS_CONTINUE:
+ return 0;
+ case WIMLIB_PROGRESS_STATUS_ABORT:
+ return WIMLIB_ERR_ABORTED_BY_PROGRESS;
+ default:
+ return WIMLIB_ERR_UNKNOWN_PROGRESS_STATUS;
+ }
+ }
+ return 0;
+}
+
+#endif
/* Chunk size for writing packed streams; can be set with
* wimlib_set_output_pack_chunk_size(). */
u32 out_pack_chunk_size;
+
+ /* Currently registered progress function for this WIMStruct, or NULL if
+ * no progress function is currently registered for this WIMStruct. */
+ wimlib_progress_func_t progfunc;
+ void *progctx;
};
static inline bool wim_is_pipable(const WIMStruct *wim)
extern int
open_wim_as_WIMStruct(const void *wim_filename_or_fd, int open_flags,
WIMStruct **wim_ret,
- wimlib_progress_func_t progress_func);
+ wimlib_progress_func_t progfunc, void *progctx);
extern int
close_wim(WIMStruct *wim);
int image,
int write_flags,
unsigned num_threads,
- wimlib_progress_func_t progress_func,
unsigned part_number,
unsigned total_parts,
struct list_head *stream_list_override,
static void recommend_man_page(int cmd, FILE *fp);
static const tchar *get_cmd_string(int cmd, bool nospace);
-static int imagex_progress_func(enum wimlib_progress_msg msg,
- const union wimlib_progress_info *info);
-
static bool imagex_be_quiet = false;
static FILE *imagex_info_file;
return wimlib_reference_resource_files(wim, set->strings,
set->num_strings,
WIMLIB_REF_FLAG_GLOB_ENABLE,
- open_flags,
- imagex_progress_func);
+ open_flags);
}
static void
last_scan_progress = *scan;
}
}
-
/* Progress callback function passed to various wimlib functions. */
-static int
+static enum wimlib_progress_status
imagex_progress_func(enum wimlib_progress_msg msg,
- const union wimlib_progress_info *info)
+ union wimlib_progress_info *info,
+ void *_ignored_context)
{
unsigned percent_done;
unsigned unit_shift;
const tchar *unit_name;
if (imagex_be_quiet)
- return 0;
+ return WIMLIB_PROGRESS_STATUS_CONTINUE;
switch (msg) {
case WIMLIB_PROGRESS_MSG_WRITE_STREAMS:
{
break;
}
fflush(imagex_info_file);
- return 0;
+ return WIMLIB_PROGRESS_STATUS_CONTINUE;
}
static unsigned
}
wim = NULL;
} else {
- ret = wimlib_open_wim(wimfile, open_flags, &wim,
- imagex_progress_func);
+ ret = wimlib_open_wim_with_progress(wimfile, open_flags, &wim,
+ imagex_progress_func, NULL);
if (ret)
goto out_free_refglobs;
#endif
if (wim) {
- ret = wimlib_extract_image(wim, image, target, extract_flags,
- imagex_progress_func);
+ ret = wimlib_extract_image(wim, image, target, extract_flags);
} else {
set_fd_to_binary_mode(STDIN_FILENO);
- ret = wimlib_extract_image_from_pipe(STDIN_FILENO,
- image_num_or_name,
- target, extract_flags,
- imagex_progress_func);
+ ret = wimlib_extract_image_from_pipe_with_progress(
+ STDIN_FILENO,
+ image_num_or_name,
+ target,
+ extract_flags,
+ imagex_progress_func,
+ NULL);
}
if (ret == 0) {
imagex_printf(T("Done applying WIM image.\n"));
}
/* Open the existing WIM, or create a new one. */
- if (cmd == CMD_APPEND)
- ret = wimlib_open_wim(wimfile, open_flags, &wim,
- imagex_progress_func);
- else
+ if (cmd == CMD_APPEND) {
+ ret = wimlib_open_wim_with_progress(wimfile, open_flags, &wim,
+ imagex_progress_func, NULL);
+ if (ret)
+ goto out_free_capture_sources;
+ } else {
ret = wimlib_create_new_wim(compression_type, &wim);
- if (ret)
- goto out_free_capture_sources;
+ if (ret)
+ goto out_free_capture_sources;
+ wimlib_register_progress_function(wim, imagex_progress_func, NULL);
+ }
/* Set chunk size if non-default. */
if (chunk_size != UINT32_MAX) {
}
for (size_t i = 0; i < base_wimfiles.num_strings; i++) {
- ret = wimlib_open_wim(base_wimfiles.strings[i],
- open_flags, &base_wims[i],
- imagex_progress_func);
+ ret = wimlib_open_wim_with_progress(
+ base_wimfiles.strings[i],
+ open_flags, &base_wims[i],
+ imagex_progress_func, NULL);
if (ret)
goto out_free_base_wims;
} else if (template_wimfile == wimfile) {
template_wim = wim;
} else {
- ret = wimlib_open_wim(template_wimfile, open_flags,
- &template_wim, imagex_progress_func);
+ ret = wimlib_open_wim_with_progress(template_wimfile,
+ open_flags,
+ &template_wim,
+ imagex_progress_func,
+ NULL);
if (ret)
goto out_free_base_wims;
}
num_sources,
name,
config_file,
- add_image_flags,
- imagex_progress_func);
+ add_image_flags);
if (ret)
goto out_free_template_wim;
info.image_count,
template_wim,
template_image,
- 0, NULL);
+ 0);
if (ret)
goto out_free_template_wim;
}
/* Write the new WIM or overwrite the existing WIM with the new image
* appended. */
if (cmd == CMD_APPEND) {
- ret = wimlib_overwrite(wim, write_flags, num_threads,
- imagex_progress_func);
+ ret = wimlib_overwrite(wim, write_flags, num_threads);
} else if (wimfile) {
ret = wimlib_write(wim, wimfile, WIMLIB_ALL_IMAGES,
- write_flags, num_threads,
- imagex_progress_func);
+ write_flags, num_threads);
} else {
ret = wimlib_write_to_fd(wim, wim_fd, WIMLIB_ALL_IMAGES,
- write_flags, num_threads,
- imagex_progress_func);
+ write_flags, num_threads);
}
out_free_template_wim:
/* template_wim may alias base_wims[0] or wim. */
wimfile = argv[0];
image_num_or_name = argv[1];
- ret = wimlib_open_wim(wimfile, open_flags, &wim,
- imagex_progress_func);
+ ret = wimlib_open_wim_with_progress(wimfile, open_flags, &wim,
+ imagex_progress_func, NULL);
if (ret)
goto out;
goto out_wimlib_free;
}
- ret = wimlib_overwrite(wim, write_flags, 0, imagex_progress_func);
+ ret = wimlib_overwrite(wim, write_flags, 0);
if (ret) {
imagex_error(T("Failed to write the file \"%"TS"\" with image "
"deleted"), wimfile);
}
wimfile = argv[0];
- ret = wimlib_open_wim(wimfile, 0, &wim, imagex_progress_func);
+ ret = wimlib_open_wim_with_progress(wimfile, 0, &wim,
+ imagex_progress_func, NULL);
if (ret)
goto out;
dest_wimfile = argv[2];
dest_name = (argc >= 4) ? argv[3] : NULL;
dest_desc = (argc >= 5) ? argv[4] : NULL;
- ret = wimlib_open_wim(src_wimfile, open_flags, &src_wim,
- imagex_progress_func);
+ ret = wimlib_open_wim_with_progress(src_wimfile, open_flags, &src_wim,
+ imagex_progress_func, NULL);
if (ret)
goto out_free_refglobs;
ret = -1;
goto out_free_src_wim;
}
- ret = wimlib_open_wim(dest_wimfile,
- open_flags | WIMLIB_OPEN_FLAG_WRITE_ACCESS,
- &dest_wim, imagex_progress_func);
+ ret = wimlib_open_wim_with_progress(dest_wimfile,
+ open_flags |
+ WIMLIB_OPEN_FLAG_WRITE_ACCESS,
+ &dest_wim,
+ imagex_progress_func,
+ NULL);
if (ret)
goto out_free_src_wim;
if (ret)
goto out_free_src_wim;
+ wimlib_register_progress_function(dest_wim,
+ imagex_progress_func, NULL);
+
if ((export_flags & WIMLIB_EXPORT_FLAG_WIMBOOT)
&& compression_type == WIMLIB_COMPRESSION_TYPE_XPRESS)
{
}
ret = wimlib_export_image(src_wim, image, dest_wim, dest_name,
- dest_desc, export_flags, imagex_progress_func);
+ dest_desc, export_flags);
if (ret) {
if (ret == WIMLIB_ERR_RESOURCE_NOT_FOUND) {
do_resource_not_found_warning(src_wimfile,
}
if (!wim_is_new)
- ret = wimlib_overwrite(dest_wim, write_flags, num_threads,
- imagex_progress_func);
+ ret = wimlib_overwrite(dest_wim, write_flags, num_threads);
else if (dest_wimfile)
ret = wimlib_write(dest_wim, dest_wimfile, WIMLIB_ALL_IMAGES,
- write_flags, num_threads,
- imagex_progress_func);
+ write_flags, num_threads);
else
ret = wimlib_write_to_fd(dest_wim, dest_wim_fd,
WIMLIB_ALL_IMAGES, write_flags,
- num_threads, imagex_progress_func);
+ num_threads);
out_free_dest_wim:
wimlib_free(dest_wim);
out_free_src_wim:
argc -= 2;
argv += 2;
- ret = wimlib_open_wim(wimfile, open_flags, &wim, imagex_progress_func);
+ ret = wimlib_open_wim_with_progress(wimfile, open_flags, &wim,
+ imagex_progress_func, NULL);
if (ret)
goto out_free_refglobs;
ret = wimlib_extract_paths(wim, image, dest_dir,
(const tchar **)argv,
num_paths,
- extract_flags | notlist_extract_flags,
- imagex_progress_func);
+ extract_flags | notlist_extract_flags);
argc -= num_paths;
argv += num_paths;
} else {
ret = wimlib_extract_pathlist(wim, image, dest_dir,
argv[0] + 1,
- extract_flags,
- imagex_progress_func);
+ extract_flags);
argc--;
argv++;
}
if (check)
open_flags |= WIMLIB_OPEN_FLAG_CHECK_INTEGRITY;
- ret = wimlib_open_wim(wimfile, open_flags, &wim, imagex_progress_func);
+ ret = wimlib_open_wim_with_progress(wimfile, open_flags, &wim,
+ imagex_progress_func, NULL);
if (ret)
goto out;
write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY;
if (nocheck)
write_flags |= WIMLIB_WRITE_FLAG_NO_CHECK_INTEGRITY;
- ret = wimlib_overwrite(wim, write_flags, 1,
- imagex_progress_func);
+ ret = wimlib_overwrite(wim, write_flags, 1);
} else {
imagex_printf(T("The file \"%"TS"\" was not modified "
"because nothing needed to be done.\n"),
goto out_usage;
}
output_path = argv[0];
- ret = wimlib_join((const tchar * const *)++argv,
- --argc,
- output_path,
- swm_open_flags,
- wim_write_flags,
- imagex_progress_func);
+ ret = wimlib_join_with_progress((const tchar * const *)++argv,
+ --argc,
+ output_path,
+ swm_open_flags,
+ wim_write_flags,
+ imagex_progress_func,
+ NULL);
out:
return ret;
wimfile = argv[0];
- ret = wimlib_open_wim(wimfile, open_flags, &wim, imagex_progress_func);
+ ret = wimlib_open_wim_with_progress(wimfile, open_flags, &wim,
+ imagex_progress_func, NULL);
if (ret)
goto out_free_refglobs;
wimfile = argv[0];
- ret = wimlib_open_wim(wimfile, open_flags, &wim, imagex_progress_func);
+ ret = wimlib_open_wim_with_progress(wimfile, open_flags, &wim,
+ imagex_progress_func, NULL);
if (ret)
goto out;
else
tprintf(T("%"PRIu64" KiB\n"), old_size >> 10);
- ret = wimlib_overwrite(wim, write_flags, num_threads,
- imagex_progress_func);
+ ret = wimlib_overwrite(wim, write_flags, num_threads);
if (ret) {
imagex_error(T("Optimization of \"%"TS"\" failed."), wimfile);
goto out_wimlib_free;
"floating-point number of megabytes."));
goto out_err;
}
- ret = wimlib_open_wim(argv[0], open_flags, &wim, imagex_progress_func);
+ ret = wimlib_open_wim_with_progress(argv[0], open_flags, &wim,
+ imagex_progress_func, NULL);
if (ret)
goto out;
- ret = wimlib_split(wim, argv[1], part_size, write_flags, imagex_progress_func);
+ ret = wimlib_split(wim, argv[1], part_size, write_flags);
wimlib_free(wim);
out:
return ret;
imagex_printf(T("Committing changes as new image...\n"));
}
- ret = wimlib_unmount_image(argv[0], unmount_flags,
- imagex_progress_func);
+ ret = wimlib_unmount_image_with_progress(argv[0], unmount_flags,
+ imagex_progress_func, NULL);
if (ret)
imagex_error(T("Failed to unmount \"%"TS"\""), argv[0]);
out:
goto out_usage;
wimfile = argv[0];
- ret = wimlib_open_wim(wimfile, open_flags, &wim, imagex_progress_func);
+ ret = wimlib_open_wim_with_progress(wimfile, open_flags, &wim,
+ imagex_progress_func, NULL);
if (ret)
goto out_free_command_str;
}
/* Execute the update commands */
- ret = wimlib_update_image(wim, image, cmds, num_cmds, update_flags,
- imagex_progress_func);
+ ret = wimlib_update_image(wim, image, cmds, num_cmds, update_flags);
if (ret)
goto out_free_cmds;
cmd.add.config_file = NULL;
cmd.add.add_flags = 0;
- ret = wimlib_update_image(wim, image, &cmd, 1,
- update_flags, imagex_progress_func);
+ ret = wimlib_update_image(wim, image, &cmd, 1, update_flags);
if (ret)
goto out_free_cmds;
}
/* Overwrite the updated WIM */
- ret = wimlib_overwrite(wim, write_flags, num_threads,
- imagex_progress_func);
+ ret = wimlib_overwrite(wim, write_flags, num_threads);
out_free_cmds:
free(cmds);
out_free_cmd_file_contents:
size_t num_sources,
const tchar *name,
const tchar *config_file,
- int add_flags,
- wimlib_progress_func_t progress_func)
+ int add_flags)
{
int ret;
struct wimlib_update_command *add_cmds;
/* Delegate the work to wimlib_update_image(). */
ret = wimlib_update_image(wim, wim->hdr.image_count, add_cmds,
- num_sources, 0, progress_func);
+ num_sources, 0);
FREE(add_cmds);
if (ret)
goto out_delete_image;
const tchar *source,
const tchar *name,
const tchar *config_file,
- int add_flags,
- wimlib_progress_func_t progress_func)
+ int add_flags)
{
/* Use the more general wimlib_add_image_multisource(). */
const struct wimlib_capture_source capture_src = {
.reserved = 0,
};
return wimlib_add_image_multisource(wim, &capture_src, 1, name,
- config_file, add_flags,
- progress_func);
+ config_file, add_flags);
}
#include "wimlib/error.h"
#include "wimlib/lookup_table.h"
#include "wimlib/paths.h"
+#include "wimlib/progress.h"
#include "wimlib/textfile.h"
#include "wimlib/wildcard.h"
* seen, inode->i_nlink will be 1. On subsequent visits of the same inode
* via additional hard links, inode->i_nlink will be greater than 1.
*/
-void
+int
do_capture_progress(struct add_image_params *params, int status,
const struct wim_inode *inode)
{
switch (status) {
case WIMLIB_SCAN_DENTRY_OK:
if (!(params->add_flags & WIMLIB_ADD_FLAG_VERBOSE))
- return;
+ return 0;
case WIMLIB_SCAN_DENTRY_UNSUPPORTED:
case WIMLIB_SCAN_DENTRY_EXCLUDED:
case WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK:
if (!(params->add_flags & WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE))
- return;
+ return 0;
}
params->progress.scan.status = status;
if (status == WIMLIB_SCAN_DENTRY_OK && inode->i_nlink == 1) {
else
params->progress.scan.num_nondirs_scanned++;
}
+
/* Call the user-provided progress function. */
- if (params->progress_func) {
- params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY,
- ¶ms->progress);
- }
+ return call_progress(params->progfunc, WIMLIB_PROGRESS_MSG_SCAN_DENTRY,
+ ¶ms->progress, params->progctx);
}
/*
WIMStruct *dest_wim,
const tchar *dest_name,
const tchar *dest_description,
- int export_flags,
- wimlib_progress_func_t progress_func)
+ int export_flags)
{
int ret;
int start_image;
memcpy(ctx->progress.extract.guid, ctx->wim->hdr.guid, WIM_GUID_LEN);
ctx->progress.extract.part_number = ctx->wim->hdr.part_number;
ctx->progress.extract.total_parts = ctx->wim->hdr.total_parts;
- if (ctx->progress_func) {
- ctx->progress_func(WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN,
- &ctx->progress);
- }
+ ret = extract_progress(ctx, WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN);
+ if (ret)
+ goto out;
+
while (ctx->num_streams_remaining) {
struct wim_header_disk pwm_hdr;
struct wim_lookup_table_entry *needed_lte;
ctx->progress.extract.total_parts = total_parts;
memcpy(ctx->progress.extract.guid,
pwm_hdr.guid, WIM_GUID_LEN);
- if (ctx->progress_func) {
- ctx->progress_func(
- WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN,
- &ctx->progress);
- }
+ ret = extract_progress(ctx,
+ WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN);
+ if (ret)
+ goto out;
}
}
}
consume_chunk_with_progress(const void *chunk, size_t size, void *_ctx)
{
struct apply_ctx *ctx = _ctx;
- wimlib_progress_func_t progress_func = ctx->progress_func;
union wimlib_progress_info *progress = &ctx->progress;
+ int ret;
if (likely(ctx->supported_features.hard_links)) {
progress->extract.completed_bytes +=
}
}
if (progress->extract.completed_bytes >= ctx->next_progress) {
- progress_func(WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS, progress);
+
+ ret = extract_progress(ctx, WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS);
+ if (ret)
+ return ret;
+
if (progress->extract.completed_bytes >=
progress->extract.total_bytes)
{
.end_stream = cbs->end_stream,
.end_stream_ctx = cbs->end_stream_ctx,
};
- if (ctx->progress_func) {
+ if (ctx->progfunc) {
ctx->saved_cbs = cbs;
cbs = &wrapper_cbs;
}
static int
extract_trees(WIMStruct *wim, struct wim_dentry **trees, size_t num_trees,
- const tchar *target, int extract_flags,
- wimlib_progress_func_t progress_func)
+ const tchar *target, int extract_flags)
{
const struct apply_operations *ops;
struct apply_ctx *ctx;
ctx->target = target;
ctx->target_nchars = tstrlen(target);
ctx->extract_flags = extract_flags;
- if (progress_func) {
- ctx->progress_func = progress_func;
+ if (ctx->wim->progfunc) {
+ ctx->progfunc = ctx->wim->progfunc;
+ ctx->progctx = ctx->wim->progctx;
ctx->progress.extract.image = wim->current_image;
ctx->progress.extract.extract_flags = (extract_flags &
WIMLIB_EXTRACT_MASK_PUBLIC);
}
}
- if (ctx->progress_func) {
- int msg;
- if (extract_flags & WIMLIB_EXTRACT_FLAG_IMAGEMODE)
- msg = WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN;
- else
- msg = WIMLIB_PROGRESS_MSG_EXTRACT_TREE_BEGIN;
- (*ctx->progress_func)(msg, &ctx->progress);
- }
+ ret = extract_progress(ctx,
+ ((extract_flags & WIMLIB_EXTRACT_FLAG_IMAGEMODE) ?
+ WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN :
+ WIMLIB_PROGRESS_MSG_EXTRACT_TREE_BEGIN));
+ if (ret)
+ goto out_cleanup;
ret = (*ops->extract)(&dentry_list, ctx);
if (ret)
goto out_cleanup;
- if (ctx->progress_func &&
- ctx->progress.extract.completed_bytes <
- ctx->progress.extract.total_bytes)
+ if (ctx->progress.extract.completed_bytes <
+ ctx->progress.extract.total_bytes)
{
ctx->progress.extract.completed_bytes =
ctx->progress.extract.total_bytes;
- (*ctx->progress_func)(WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS,
- &ctx->progress);
+ ret = extract_progress(ctx, WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS);
+ if (ret)
+ goto out_cleanup;
}
- if (ctx->progress_func) {
- int msg;
- if (extract_flags & WIMLIB_EXTRACT_FLAG_IMAGEMODE)
- msg = WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END;
- else
- msg = WIMLIB_PROGRESS_MSG_EXTRACT_TREE_END;
- (*ctx->progress_func)(msg, &ctx->progress);
- }
- ret = 0;
+ ret = extract_progress(ctx,
+ ((extract_flags & WIMLIB_EXTRACT_FLAG_IMAGEMODE) ?
+ WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END :
+ WIMLIB_PROGRESS_MSG_EXTRACT_TREE_END));
out_cleanup:
destroy_stream_list(&ctx->stream_list);
destroy_dentry_list(&dentry_list);
static int
do_wimlib_extract_paths(WIMStruct *wim, int image, const tchar *target,
const tchar * const *paths, size_t num_paths,
- int extract_flags, wimlib_progress_func_t progress_func)
+ int extract_flags)
{
int ret;
struct wim_dentry **trees;
goto out_free_trees;
}
- ret = extract_trees(wim, trees, num_trees,
- target, extract_flags, progress_func);
+ ret = extract_trees(wim, trees, num_trees, target, extract_flags);
out_free_trees:
FREE(trees);
return ret;
static int
extract_single_image(WIMStruct *wim, int image,
- const tchar *target, int extract_flags,
- wimlib_progress_func_t progress_func)
+ const tchar *target, int extract_flags)
{
const tchar *path = WIMLIB_WIM_ROOT_PATH;
extract_flags |= WIMLIB_EXTRACT_FLAG_IMAGEMODE;
- return do_wimlib_extract_paths(wim, image, target, &path, 1,
- extract_flags, progress_func);
+ return do_wimlib_extract_paths(wim, image, target, &path, 1, extract_flags);
}
static const tchar * const filename_forbidden_chars =
/* Extracts all images from the WIM to the directory @target, with the images
* placed in subdirectories named by their image names. */
static int
-extract_all_images(WIMStruct *wim,
- const tchar *target,
- int extract_flags,
- wimlib_progress_func_t progress_func)
+extract_all_images(WIMStruct *wim, const tchar *target, int extract_flags)
{
size_t image_name_max_len = max(xml_get_max_image_name_len(wim), 20);
size_t output_path_len = tstrlen(target);
* Use image number instead. */
tsprintf(buf + output_path_len + 1, T("%d"), image);
}
- ret = extract_single_image(wim, image, buf, extract_flags,
- progress_func);
+ ret = extract_single_image(wim, image, buf, extract_flags);
if (ret)
return ret;
}
}
static int
-do_wimlib_extract_image(WIMStruct *wim,
- int image,
- const tchar *target,
- int extract_flags,
- wimlib_progress_func_t progress_func)
+do_wimlib_extract_image(WIMStruct *wim, int image, const tchar *target,
+ int extract_flags)
{
if (extract_flags & (WIMLIB_EXTRACT_FLAG_NO_PRESERVE_DIR_STRUCTURE |
WIMLIB_EXTRACT_FLAG_TO_STDOUT |
return WIMLIB_ERR_INVALID_PARAM;
if (image == WIMLIB_ALL_IMAGES)
- return extract_all_images(wim, target, extract_flags,
- progress_func);
+ return extract_all_images(wim, target, extract_flags);
else
- return extract_single_image(wim, image, target, extract_flags,
- progress_func);
+ return extract_single_image(wim, image, target, extract_flags);
}
WIMLIBAPI int
wimlib_extract_paths(WIMStruct *wim, int image, const tchar *target,
const tchar * const *paths, size_t num_paths,
- int extract_flags, wimlib_progress_func_t progress_func)
+ int extract_flags)
{
if (extract_flags & ~WIMLIB_EXTRACT_MASK_PUBLIC)
return WIMLIB_ERR_INVALID_PARAM;
return do_wimlib_extract_paths(wim, image, target, paths, num_paths,
- extract_flags, progress_func);
+ extract_flags);
}
WIMLIBAPI int
wimlib_extract_pathlist(WIMStruct *wim, int image, const tchar *target,
- const tchar *path_list_file, int extract_flags,
- wimlib_progress_func_t progress_func)
+ const tchar *path_list_file, int extract_flags)
{
int ret;
tchar **paths;
ret = wimlib_extract_paths(wim, image, target,
(const tchar * const *)paths, num_paths,
- extract_flags, progress_func);
+ extract_flags);
FREE(paths);
FREE(mem);
return ret;
}
WIMLIBAPI int
-wimlib_extract_image_from_pipe(int pipe_fd, const tchar *image_num_or_name,
- const tchar *target, int extract_flags,
- wimlib_progress_func_t progress_func)
+wimlib_extract_image_from_pipe_with_progress(int pipe_fd,
+ const tchar *image_num_or_name,
+ const tchar *target,
+ int extract_flags,
+ wimlib_progress_func_t progfunc,
+ void *progctx)
{
int ret;
WIMStruct *pwm;
* the pipable WIM. Caveats: Unlike getting a WIMStruct with
* wimlib_open_wim(), getting a WIMStruct in this way will result in
* an empty lookup table, no XML data read, and no filename set. */
- ret = open_wim_as_WIMStruct(&pipe_fd,
- WIMLIB_OPEN_FLAG_FROM_PIPE,
- &pwm, progress_func);
+ ret = open_wim_as_WIMStruct(&pipe_fd, WIMLIB_OPEN_FLAG_FROM_PIPE, &pwm,
+ progfunc, progctx);
if (ret)
return ret;
}
/* Extract the image. */
extract_flags |= WIMLIB_EXTRACT_FLAG_FROM_PIPE;
- ret = do_wimlib_extract_image(pwm, image, target,
- extract_flags, progress_func);
+ ret = do_wimlib_extract_image(pwm, image, target, extract_flags);
/* Clean up and return. */
out_wimlib_free:
wimlib_free(pwm);
return ret;
}
+
+WIMLIBAPI int
+wimlib_extract_image_from_pipe(int pipe_fd, const tchar *image_num_or_name,
+ const tchar *target, int extract_flags)
+{
+ return wimlib_extract_image_from_pipe_with_progress(pipe_fd,
+ image_num_or_name,
+ target,
+ extract_flags,
+ NULL,
+ NULL);
+}
+
WIMLIBAPI int
wimlib_extract_image(WIMStruct *wim, int image, const tchar *target,
- int extract_flags, wimlib_progress_func_t progress_func)
+ int extract_flags)
{
if (extract_flags & ~WIMLIB_EXTRACT_MASK_PUBLIC)
return WIMLIB_ERR_INVALID_PARAM;
- return do_wimlib_extract_image(wim, image, target, extract_flags,
- progress_func);
+ return do_wimlib_extract_image(wim, image, target, extract_flags);
}
#include "wimlib/error.h"
#include "wimlib/file_io.h"
#include "wimlib/integrity.h"
+#include "wimlib/progress.h"
#include "wimlib/resource.h"
#include "wimlib/sha1.h"
#include "wimlib/wim.h"
* If @old_table is non-NULL, the byte after the last byte that was checked
* in the old table. Must be less than or equal to new_check_end.
*
- * @progress_func:
- * If non-NULL, a progress function that will be called after every
- * calculated chunk.
- *
* @integrity_table_ret:
* On success, a pointer to the calculated integrity table is written into
* this location.
off_t new_check_end,
const struct integrity_table *old_table,
off_t old_check_end,
- wimlib_progress_func_t progress_func,
- struct integrity_table **integrity_table_ret)
+ struct integrity_table **integrity_table_ret,
+ wimlib_progress_func_t progfunc,
+ void *progctx)
{
int ret;
size_t chunk_size = INTEGRITY_CHUNK_SIZE;
u64 offset = WIM_HEADER_DISK_SIZE;
union wimlib_progress_info progress;
- if (progress_func) {
- progress.integrity.total_bytes = new_check_bytes;
- progress.integrity.total_chunks = new_num_chunks;
- progress.integrity.completed_chunks = 0;
- progress.integrity.completed_bytes = 0;
- progress.integrity.chunk_size = chunk_size;
- progress.integrity.filename = NULL;
- progress_func(WIMLIB_PROGRESS_MSG_CALC_INTEGRITY,
- &progress);
- }
+ progress.integrity.total_bytes = new_check_bytes;
+ progress.integrity.total_chunks = new_num_chunks;
+ progress.integrity.completed_chunks = 0;
+ progress.integrity.completed_bytes = 0;
+ progress.integrity.chunk_size = chunk_size;
+ progress.integrity.filename = NULL;
+
+ ret = call_progress(progfunc, WIMLIB_PROGRESS_MSG_CALC_INTEGRITY,
+ &progress, progctx);
+ if (ret)
+ goto out_free_new_table;
for (u32 i = 0; i < new_num_chunks; i++) {
size_t this_chunk_size;
/* Calculate the SHA1 message digest of this chunk */
ret = calculate_chunk_sha1(in_fd, this_chunk_size,
offset, new_table->sha1sums[i]);
- if (ret) {
- FREE(new_table);
- return ret;
- }
+ if (ret)
+ goto out_free_new_table;
}
offset += this_chunk_size;
- if (progress_func) {
- progress.integrity.completed_chunks++;
- progress.integrity.completed_bytes += this_chunk_size;
- progress_func(WIMLIB_PROGRESS_MSG_CALC_INTEGRITY,
- &progress);
- }
+
+ progress.integrity.completed_chunks++;
+ progress.integrity.completed_bytes += this_chunk_size;
+ ret = call_progress(progfunc, WIMLIB_PROGRESS_MSG_CALC_INTEGRITY,
+ &progress, progctx);
+ if (ret)
+ goto out_free_new_table;
}
*integrity_table_ret = new_table;
return 0;
+
+out_free_new_table:
+ FREE(new_table);
+ return ret;
}
/*
* If nonzero, the offset of the byte directly following the old lookup
* table in the WIM.
*
- * @progress_func
- * If non-NULL, a progress function that will be called after every
- * calculated chunk.
- *
* Return values:
* WIMLIB_ERR_SUCCESS (0)
* WIMLIB_ERR_NOMEM
int
write_integrity_table(WIMStruct *wim,
off_t new_lookup_table_end,
- off_t old_lookup_table_end,
- wimlib_progress_func_t progress_func)
+ off_t old_lookup_table_end)
{
struct integrity_table *old_table;
struct integrity_table *new_table;
ret = calculate_integrity_table(&wim->out_fd, new_lookup_table_end,
old_table, old_lookup_table_end,
- progress_func, &new_table);
+ &new_table, wim->progfunc, wim->progctx);
if (ret)
goto out_free_old_table;
* Number of bytes in the WIM that need to be checked (offset of end of the
* lookup table minus offset of end of the header).
*
- * @progress_func
- * If non-NULL, a progress function that will be called after every
- * verified chunk.
- *
* Returns:
* > 0 (WIMLIB_ERR_READ, WIMLIB_ERR_UNEXPECTED_END_OF_FILE) on error
* 0 (WIM_INTEGRITY_OK) if the integrity was checked successfully and there
verify_integrity(struct filedes *in_fd, const tchar *filename,
const struct integrity_table *table,
u64 bytes_to_check,
- wimlib_progress_func_t progress_func)
+ wimlib_progress_func_t progfunc, void *progctx)
{
int ret;
u64 offset = WIM_HEADER_DISK_SIZE;
u8 sha1_md[SHA1_HASH_SIZE];
union wimlib_progress_info progress;
- if (progress_func) {
- progress.integrity.total_bytes = bytes_to_check;
- progress.integrity.total_chunks = table->num_entries;
- progress.integrity.completed_chunks = 0;
- progress.integrity.completed_bytes = 0;
- progress.integrity.chunk_size = table->chunk_size;
- progress.integrity.filename = filename;
- progress_func(WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY,
- &progress);
- }
+ progress.integrity.total_bytes = bytes_to_check;
+ progress.integrity.total_chunks = table->num_entries;
+ progress.integrity.completed_chunks = 0;
+ progress.integrity.completed_bytes = 0;
+ progress.integrity.chunk_size = table->chunk_size;
+ progress.integrity.filename = filename;
+
+ ret = call_progress(progfunc, WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY,
+ &progress, progctx);
+ if (ret)
+ return ret;
+
for (u32 i = 0; i < table->num_entries; i++) {
size_t this_chunk_size;
if (i == table->num_entries - 1)
return WIM_INTEGRITY_NOT_OK;
offset += this_chunk_size;
- if (progress_func) {
- progress.integrity.completed_chunks++;
- progress.integrity.completed_bytes += this_chunk_size;
- progress_func(WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY,
- &progress);
- }
+ progress.integrity.completed_chunks++;
+ progress.integrity.completed_bytes += this_chunk_size;
+
+ ret = call_progress(progfunc, WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY,
+ &progress, progctx);
+ if (ret)
+ return ret;
}
return WIM_INTEGRITY_OK;
}
* @wim:
* The WIM, opened for reading.
*
- * @progress_func
- * If non-NULL, a progress function that will be called after every
- * verified chunk.
- *
* Returns:
* > 0 (WIMLIB_ERR_INVALID_INTEGRITY_TABLE, WIMLIB_ERR_READ,
* WIMLIB_ERR_UNEXPECTED_END_OF_FILE) on error
* information.
*/
int
-check_wim_integrity(WIMStruct *wim, wimlib_progress_func_t progress_func)
+check_wim_integrity(WIMStruct *wim)
{
int ret;
u64 bytes_to_check;
if (ret)
return ret;
ret = verify_integrity(&wim->in_fd, wim->filename, table,
- bytes_to_check, progress_func);
+ bytes_to_check, wim->progfunc, wim->progctx);
FREE(table);
return ret;
}
return 0;
}
-/* API function documented in wimlib.h */
WIMLIBAPI int
-wimlib_join(const tchar * const *swm_names,
- unsigned num_swms,
- const tchar *output_path,
- int swm_open_flags,
- int wim_write_flags,
- wimlib_progress_func_t progress_func)
+wimlib_join_with_progress(const tchar * const *swm_names,
+ unsigned num_swms,
+ const tchar *output_path,
+ int swm_open_flags,
+ int wim_write_flags,
+ wimlib_progress_func_t progfunc,
+ void *progctx)
{
int ret;
unsigned i;
for (i = 0, j = 0; i < num_swms; i++) {
WIMStruct *swm;
- ret = wimlib_open_wim(swm_names[i], swm_open_flags, &swm,
- progress_func);
+ ret = wimlib_open_wim_with_progress(swm_names[i],
+ swm_open_flags,
+ &swm,
+ progfunc,
+ progctx);
if (ret)
goto out_free_swms;
if (swm->hdr.part_number == 1 && swm0 == NULL)
wim_write_flags |
WIMLIB_WRITE_FLAG_STREAMS_OK |
WIMLIB_WRITE_FLAG_RETAIN_GUID,
- 1, progress_func);
+ 1);
out_free_swms:
for (i = 0; i < num_additional_swms + 1; i++)
wimlib_free(additional_swms[i]);
wimlib_free(swm0);
return ret;
}
+
+/* API function documented in wimlib.h */
+WIMLIBAPI int
+wimlib_join(const tchar * const *swm_names,
+ unsigned num_swms,
+ const tchar *output_path,
+ int swm_open_flags,
+ int wim_write_flags)
+{
+ return wimlib_join_with_progress(swm_names, num_swms, output_path,
+ swm_open_flags, wim_write_flags,
+ NULL, NULL);
+}
#include "wimlib/lookup_table.h"
#include "wimlib/metadata.h"
#include "wimlib/paths.h"
+#include "wimlib/progress.h"
#include "wimlib/reparse.h"
#include "wimlib/resource.h"
#include "wimlib/timestamp.h"
/* Overwrites the WIM file, with changes saved. */
static int
-rebuild_wim(struct wimfs_context *ctx, int write_flags,
- wimlib_progress_func_t progress_func)
+rebuild_wim(struct wimfs_context *ctx, int write_flags)
{
int ret;
struct wim_lookup_table_entry *lte, *tmp;
}
xml_update_image_info(wim, wim->current_image);
- ret = wimlib_overwrite(wim, write_flags, 0, progress_func);
+ ret = wimlib_overwrite(wim, write_flags, 0);
if (ret)
ERROR("Failed to commit changes to mounted WIM image");
return ret;
pid_t daemon_pid;
int mount_flags;
int status;
- wimlib_progress_func_t progress_func;
+ wimlib_progress_func_t progfunc;
+ void *progctx;
};
struct daemon_msg_handler_context {
ERROR_WITH_ERRNO("Failed to send status to unmount process");
}
-static int
+static enum wimlib_progress_status
unmount_progress_func(enum wimlib_progress_msg msg,
- const union wimlib_progress_info *info)
+ union wimlib_progress_info *info, void *_ignored_context)
{
if (msg == WIMLIB_PROGRESS_MSG_WRITE_STREAMS) {
struct msg_write_streams_progress msg = {
"to unmount process");
}
}
- return 0;
+ return WIMLIB_PROGRESS_STATUS_CONTINUE;
}
static void
int status = 0;
int ret;
int unmount_flags;
- wimlib_progress_func_t progress_func;
DEBUG("Handling unmount request msg");
}
unmount_flags = msg->unmount_flags;
- if (msg->want_progress_messages)
- progress_func = unmount_progress_func;
- else
- progress_func = NULL;
+
+ wimlib_register_progress_function(wimfs_ctx->wim,
+ (msg->want_progress_messages ?
+ unmount_progress_func : NULL),
+ NULL);
ret = send_daemon_info_msg(wimfs_ctx->daemon_to_unmount_mq, getpid(),
wimfs_ctx->mount_flags);
write_flags |= WIMLIB_WRITE_FLAG_REBUILD;
if (unmount_flags & WIMLIB_UNMOUNT_FLAG_RECOMPRESS)
write_flags |= WIMLIB_WRITE_FLAG_RECOMPRESS;
- status = rebuild_wim(wimfs_ctx, write_flags,
- progress_func);
+ status = rebuild_wim(wimfs_ctx, write_flags);
}
} else {
DEBUG("Read-only mount");
if (msg->hdr.msg_size < sizeof(*msg))
return WIMLIB_ERR_INVALID_UNMOUNT_MESSAGE;
- if (handler_ctx->progress_func) {
- handler_ctx->progress_func(WIMLIB_PROGRESS_MSG_WRITE_STREAMS,
- &msg->info);
- }
- return 0;
+ return call_progress(handler_ctx->progfunc,
+ WIMLIB_PROGRESS_MSG_WRITE_STREAMS,
+ (union wimlib_progress_info *)&msg->info,
+ handler_ctx->progctx);
}
static int
/* API function documented in wimlib.h */
WIMLIBAPI int
-wimlib_unmount_image(const char *dir, int unmount_flags,
- wimlib_progress_func_t progress_func)
+wimlib_unmount_image_with_progress(const tchar *dir, int unmount_flags,
+ wimlib_progress_func_t progfunc, void *progctx)
{
int ret;
struct wimfs_context wimfs_ctx;
ret = send_unmount_request_msg(wimfs_ctx.unmount_to_daemon_mq,
unmount_flags,
- progress_func != NULL);
+ progfunc != NULL);
if (ret != 0)
goto out_close_message_queues;
.timeout_seconds = 5,
},
.daemon_pid = 0,
- .progress_func = progress_func,
+ .progfunc = progfunc,
+ .progctx = progctx,
};
ret = message_loop(wimfs_ctx.daemon_to_unmount_mq,
}
WIMLIBAPI int
-wimlib_unmount_image(const tchar *dir, int unmount_flags,
- wimlib_progress_func_t progress_func)
+wimlib_unmount_image_with_progress(const tchar *dir, int unmount_flags,
+ wimlib_progress_func_t progfunc, void *progctx)
{
return mount_unsupported_error();
}
}
#endif /* !WITH_FUSE */
+
+
+WIMLIBAPI int
+wimlib_unmount_image(const tchar *dir, int unmount_flags)
+{
+ return wimlib_unmount_image_with_progress(dir, unmount_flags, NULL, NULL);
+}
goto out;
}
params->progress.scan.cur_path = path;
- do_capture_progress(params, WIMLIB_SCAN_DENTRY_UNSUPPORTED, NULL);
- ret = 0;
+ ret = do_capture_progress(params, WIMLIB_SCAN_DENTRY_UNSUPPORTED, NULL);
goto out;
}
out_progress:
params->progress.scan.cur_path = path;
if (root == NULL)
- do_capture_progress(params, WIMLIB_SCAN_DENTRY_EXCLUDED, NULL);
+ ret = do_capture_progress(params, WIMLIB_SCAN_DENTRY_EXCLUDED, NULL);
else
- do_capture_progress(params, WIMLIB_SCAN_DENTRY_OK, inode);
+ ret = do_capture_progress(params, WIMLIB_SCAN_DENTRY_OK, inode);
out:
if (ret == 0)
*root_ret = root;
const tchar * const *resource_wimfiles,
unsigned num_resource_wimfiles,
int ref_flags,
- int open_flags,
- wimlib_progress_func_t progress_func)
+ int open_flags)
{
WIMStruct **resource_wims;
unsigned i;
for (i = 0; i < num_resource_wimfiles; i++) {
DEBUG("Referencing resources from path \"%"TS"\"",
resource_wimfiles[i]);
- ret = wimlib_open_wim(resource_wimfiles[i], open_flags,
- &resource_wims[i], progress_func);
+ ret = wimlib_open_wim_with_progress(resource_wimfiles[i],
+ open_flags,
+ &resource_wims[i],
+ wim->progfunc,
+ wim->progctx);
if (ret)
goto out_free_resource_wims;
}
static int
reference_resource_glob(WIMStruct *wim, const tchar *refglob,
- int ref_flags, int open_flags,
- wimlib_progress_func_t progress_func)
+ int ref_flags, int open_flags)
{
glob_t globbuf;
int ret;
&refglob,
1,
ref_flags,
- open_flags,
- progress_func);
+ open_flags);
}
} else {
ERROR_WITH_ERRNO("Failed to process glob \"%"TS"\"", refglob);
(const tchar * const *)globbuf.gl_pathv,
globbuf.gl_pathc,
ref_flags,
- open_flags,
- progress_func);
+ open_flags);
globfree(&globbuf);
return ret;
}
const tchar * const * resource_wimfiles_or_globs,
unsigned count,
int ref_flags,
- int open_flags,
- wimlib_progress_func_t progress_func)
+ int open_flags)
{
unsigned i;
int ret;
ret = reference_resource_glob(wim,
resource_wimfiles_or_globs[i],
ref_flags,
- open_flags,
- progress_func);
+ open_flags);
if (ret)
return ret;
}
return 0;
} else {
return reference_resource_paths(wim, resource_wimfiles_or_globs,
- count, ref_flags,
- open_flags, progress_func);
+ count, ref_flags, open_flags);
}
}
#include "wimlib/list.h"
#include "wimlib/lookup_table.h"
#include "wimlib/metadata.h"
+#include "wimlib/progress.h"
#include "wimlib/resource.h"
#include "wimlib/wim.h"
#include "wimlib/write.h"
static int
write_split_wim(WIMStruct *orig_wim, const tchar *swm_name,
- struct swm_info *swm_info, int write_flags,
- wimlib_progress_func_t progress_func)
+ struct swm_info *swm_info, int write_flags)
{
size_t swm_name_len;
tchar *swm_name_buf;
for (part_number = 1; part_number <= swm_info->num_parts; part_number++) {
int part_write_flags;
+ wimlib_progress_func_t progfunc;
if (part_number != 1) {
tsprintf(swm_name_buf + swm_base_name_len,
}
progress.split.cur_part_number = part_number;
- if (progress_func) {
- progress_func(WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART,
- &progress);
- }
+
+ ret = call_progress(orig_wim->progfunc,
+ WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART,
+ &progress,
+ orig_wim->progctx);
+ if (ret)
+ return ret;
part_write_flags = write_flags;
part_write_flags |= WIMLIB_WRITE_FLAG_USE_EXISTING_TOTALBYTES;
if (part_number != 1)
part_write_flags |= WIMLIB_WRITE_FLAG_NO_METADATA;
+ progfunc = orig_wim->progfunc;
+ orig_wim->progfunc = NULL;
ret = write_wim_part(orig_wim,
swm_name_buf,
WIMLIB_ALL_IMAGES,
part_write_flags,
1,
- NULL,
part_number,
swm_info->num_parts,
&swm_info->parts[part_number - 1].stream_list,
guid);
+ orig_wim->progfunc = progfunc;
if (ret)
return ret;
progress.split.completed_bytes += swm_info->parts[part_number - 1].size;
- if (progress_func) {
- progress_func(WIMLIB_PROGRESS_MSG_SPLIT_END_PART,
- &progress);
- }
+
+ ret = call_progress(orig_wim->progfunc,
+ WIMLIB_PROGRESS_MSG_SPLIT_END_PART,
+ &progress,
+ orig_wim->progctx);
+ if (ret)
+ return ret;
}
return 0;
}
/* API function documented in wimlib.h */
WIMLIBAPI int
wimlib_split(WIMStruct *wim, const tchar *swm_name,
- u64 part_size, int write_flags,
- wimlib_progress_func_t progress_func)
+ u64 part_size, int write_flags)
{
struct swm_info swm_info;
unsigned i;
if (ret)
goto out_free_swm_info;
- ret = write_split_wim(wim, swm_name, &swm_info, write_flags,
- progress_func);
+ ret = write_split_wim(wim, swm_name, &swm_info, write_flags);
out_free_swm_info:
FREE(swm_info.parts);
return ret;
WIMLIBAPI int
wimlib_reference_template_image(WIMStruct *wim, int new_image,
WIMStruct *template_wim, int template_image,
- int flags, wimlib_progress_func_t progress_func)
+ int flags)
{
int ret;
struct wim_image_metadata *new_imd;
*root_p = NULL;
params->progress.scan.cur_path = full_path;
params->progress.scan.symlink_target = deref_name_buf;
- do_capture_progress(params,
- WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK,
- NULL);
- return 0;
+ return do_capture_progress(params,
+ WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK,
+ NULL);
}
inode->i_not_rpfixed = 0;
}
goto out;
}
params->progress.scan.cur_path = full_path;
- do_capture_progress(params, WIMLIB_SCAN_DENTRY_UNSUPPORTED, NULL);
- ret = 0;
+ ret = do_capture_progress(params, WIMLIB_SCAN_DENTRY_UNSUPPORTED, NULL);
goto out;
}
out_progress:
params->progress.scan.cur_path = full_path;
if (likely(tree))
- do_capture_progress(params, WIMLIB_SCAN_DENTRY_OK, inode);
+ ret = do_capture_progress(params, WIMLIB_SCAN_DENTRY_OK, inode);
else
- do_capture_progress(params, WIMLIB_SCAN_DENTRY_EXCLUDED, NULL);
+ ret = do_capture_progress(params, WIMLIB_SCAN_DENTRY_EXCLUDED, NULL);
out:
if (likely(ret == 0))
*tree_ret = tree;
# include "wimlib/ntfs_3g.h" /* for do_ntfs_umount() */
#endif
#include "wimlib/paths.h"
+#include "wimlib/progress.h"
#include "wimlib/xml.h"
#include <errno.h>
static int
handle_conflict(struct wim_dentry *branch, struct wim_dentry *existing,
struct update_command_journal *j,
- int add_flags, wimlib_progress_func_t progress_func)
+ int add_flags,
+ wimlib_progress_func_t progfunc, void *progctx)
{
bool branch_is_dir = dentry_is_directory(branch);
bool existing_is_dir = dentry_is_directory(existing);
unlink_dentry(new_child);
if (existing_child) {
ret = handle_conflict(new_child, existing_child,
- j, add_flags, progress_func);
+ j, add_flags,
+ progfunc, progctx);
} else {
ret = journaled_link(j, new_child, existing);
}
/* Replace nondirectory file */
struct wim_dentry *parent;
int ret;
+ union wimlib_progress_info info;
parent = existing->parent;
if (ret)
return ret;
- if (progress_func && (add_flags & WIMLIB_ADD_FLAG_VERBOSE)) {
- union wimlib_progress_info info;
- info.replace.path_in_wim = existing->_full_path;
- progress_func(WIMLIB_PROGRESS_MSG_REPLACE_FILE_IN_WIM, &info);
- }
- return 0;
+ info.replace.path_in_wim = existing->_full_path;
+ return call_progress(progfunc,
+ WIMLIB_PROGRESS_MSG_REPLACE_FILE_IN_WIM,
+ &info, progctx);
}
}
static int
do_attach_branch(struct wim_dentry *branch, const utf16lechar *target,
struct update_command_journal *j,
- int add_flags, wimlib_progress_func_t progress_func)
+ int add_flags, wimlib_progress_func_t progfunc, void *progctx)
{
struct wim_dentry *parent;
struct wim_dentry *existing;
/* Last component */
if (existing) {
- return handle_conflict(branch, existing, j,
- add_flags, progress_func);
+ return handle_conflict(branch, existing, j, add_flags,
+ progfunc, progctx);
} else {
return journaled_link(j, branch, parent);
}
*/
static int
attach_branch(struct wim_dentry *branch, const tchar *target_tstr,
- struct update_command_journal *j,
- int add_flags, wimlib_progress_func_t progress_func)
+ struct update_command_journal *j, int add_flags,
+ wimlib_progress_func_t progfunc, void *progctx)
{
int ret;
const utf16lechar *target;
if (ret)
goto out_free_target;
- ret = do_attach_branch(branch, target, j, add_flags, progress_func);
+ ret = do_attach_branch(branch, target, j, add_flags, progfunc, progctx);
if (ret)
goto out_free_target;
/* branch was successfully committed to the journal */
const struct wimlib_update_command *add_cmd,
struct wim_inode_table *inode_table,
struct wim_sd_set *sd_set,
- struct list_head *unhashed_streams,
- wimlib_progress_func_t progress_func)
+ struct list_head *unhashed_streams)
{
int ret;
int add_flags;
params.add_flags = add_flags;
params.extra_arg = extra_arg;
- params.progress_func = progress_func;
+ params.progfunc = wim->progfunc;
+ params.progctx = wim->progctx;
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);
+ ret = call_progress(params.progfunc, WIMLIB_PROGRESS_MSG_SCAN_BEGIN,
+ ¶ms.progress, params.progctx);
+ if (ret)
+ goto out_destroy_config;
if (WIMLIB_IS_WIM_ROOT_PATH(wim_target_path))
params.add_flags |= WIMLIB_ADD_FLAG_ROOT;
if (ret)
goto out_destroy_config;
- if (progress_func)
- progress_func(WIMLIB_PROGRESS_MSG_SCAN_END, ¶ms.progress);
+ ret = call_progress(params.progfunc, WIMLIB_PROGRESS_MSG_SCAN_END,
+ ¶ms.progress, params.progctx);
+ if (ret) {
+ free_dentry_tree(branch, wim->lookup_table);
+ goto out_cleanup_after_capture;
+ }
if (WIMLIB_IS_WIM_ROOT_PATH(wim_target_path) &&
branch && !dentry_is_directory(branch))
}
ret = attach_branch(branch, wim_target_path, j,
- add_flags, params.progress_func);
+ add_flags, params.progfunc, params.progctx);
if (ret)
goto out_cleanup_after_capture;
WIMLIB_IS_WIM_ROOT_PATH(wim_target_path))
{
params.add_flags = 0;
- params.progress_func = NULL;
+ params.progfunc = NULL;
params.config = NULL;
/* If a capture configuration file was explicitly specified when
if (ret)
goto out_cleanup_after_capture;
- ret = attach_branch(branch, wimboot_cfgfile, j, 0, NULL);
+ ret = attach_branch(branch, wimboot_cfgfile, j, 0, NULL, NULL);
if (ret)
goto out_cleanup_after_capture;
}
execute_update_commands(WIMStruct *wim,
const struct wimlib_update_command *cmds,
size_t num_cmds,
- int update_flags,
- wimlib_progress_func_t progress_func)
+ int update_flags)
{
struct wim_inode_table *inode_table;
struct wim_sd_set *sd_set;
for (size_t i = 0; i < num_cmds; i++) {
DEBUG("Executing update command %zu of %zu (op=%"TS")",
i + 1, num_cmds, update_op_to_str(cmds[i].op));
- if (update_flags & WIMLIB_UPDATE_FLAG_SEND_PROGRESS &&
- progress_func)
- {
- info.update.command = &cmds[i];
- (*progress_func)(WIMLIB_PROGRESS_MSG_UPDATE_BEGIN_COMMAND,
- &info);
+ info.update.command = &cmds[i];
+ if (update_flags & WIMLIB_UPDATE_FLAG_SEND_PROGRESS) {
+ ret = call_progress(wim->progfunc,
+ WIMLIB_PROGRESS_MSG_UPDATE_BEGIN_COMMAND,
+ &info, wim->progctx);
+ if (ret)
+ goto rollback;
}
+
ret = WIMLIB_ERR_INVALID_PARAM;
switch (cmds[i].op) {
case WIMLIB_UPDATE_OP_ADD:
ret = execute_add_command(j, wim, &cmds[i], inode_table,
- sd_set, &unhashed_streams,
- progress_func);
+ sd_set, &unhashed_streams);
break;
case WIMLIB_UPDATE_OP_DELETE:
ret = execute_delete_command(j, wim, &cmds[i]);
if (unlikely(ret))
goto rollback;
info.update.completed_commands++;
- if (update_flags & WIMLIB_UPDATE_FLAG_SEND_PROGRESS &&
- progress_func)
- {
- (*progress_func)(WIMLIB_PROGRESS_MSG_UPDATE_END_COMMAND,
- &info);
+ if (update_flags & WIMLIB_UPDATE_FLAG_SEND_PROGRESS) {
+ ret = call_progress(wim->progfunc,
+ WIMLIB_PROGRESS_MSG_UPDATE_END_COMMAND,
+ &info, wim->progctx);
+ if (ret)
+ goto rollback;
}
next_command(j);
}
int image,
const struct wimlib_update_command *cmds,
size_t num_cmds,
- int update_flags,
- wimlib_progress_func_t progress_func)
+ int update_flags)
{
int ret;
struct wimlib_update_command *cmds_copy;
/* Actually execute the update commands. */
DEBUG("Executing %zu update commands", num_cmds);
- ret = execute_update_commands(wim, cmds_copy, num_cmds, update_flags,
- progress_func);
+ ret = execute_update_commands(wim, cmds_copy, num_cmds, update_flags);
if (ret)
goto out_free_cmds_copy;
static int
update1(WIMStruct *wim, int image, const struct wimlib_update_command *cmd)
{
- return wimlib_update_image(wim, image, cmd, 1, 0, NULL);
+ return wimlib_update_image(wim, image, cmd, 1, 0);
}
WIMLIBAPI int
= T("The WIM file (or parts of it) is encrypted"),
[WIMLIB_ERR_WIMBOOT]
= T("Failed to set WIMBoot pointer data"),
+ [WIMLIB_ERR_ABORTED_BY_PROGRESS]
+ = T("The operation was aborted by the library user"),
+ [WIMLIB_ERR_UNKNOWN_PROGRESS_STATUS]
+ = T("The user-provided progress function returned an unrecognized value"),
};
/* API function documented in wimlib.h */
&wim->out_pack_chunk_size);
}
+WIMLIBAPI void
+wimlib_register_progress_function(WIMStruct *wim,
+ wimlib_progress_func_t progfunc,
+ void *progctx)
+{
+ wim->progfunc = progfunc;
+ wim->progctx = progctx;
+}
+
static int
open_wim_file(const tchar *filename, struct filedes *fd_ret)
{
* lookup table, and optionally checks the integrity.
*/
static int
-begin_read(WIMStruct *wim, const void *wim_filename_or_fd,
- int open_flags, wimlib_progress_func_t progress_func)
+begin_read(WIMStruct *wim, const void *wim_filename_or_fd, int open_flags)
{
int ret;
int xml_num_images;
}
if (open_flags & WIMLIB_OPEN_FLAG_CHECK_INTEGRITY) {
- ret = check_wim_integrity(wim, progress_func);
+ ret = check_wim_integrity(wim);
if (ret == WIM_INTEGRITY_NONEXISTENT) {
WARNING("No integrity information for `%"TS"'; skipping "
"integrity check.", wimfile);
int
open_wim_as_WIMStruct(const void *wim_filename_or_fd, int open_flags,
- WIMStruct **wim_ret, wimlib_progress_func_t progress_func)
+ WIMStruct **wim_ret,
+ wimlib_progress_func_t progfunc, void *progctx)
{
WIMStruct *wim;
int ret;
if (wim == NULL)
return WIMLIB_ERR_NOMEM;
- ret = begin_read(wim, wim_filename_or_fd, open_flags, progress_func);
+ wim->progfunc = progfunc;
+ wim->progctx = progctx;
+
+ ret = begin_read(wim, wim_filename_or_fd, open_flags);
if (ret) {
wimlib_free(wim);
return ret;
/* API function documented in wimlib.h */
WIMLIBAPI int
-wimlib_open_wim(const tchar *wimfile, int open_flags,
- WIMStruct **wim_ret, wimlib_progress_func_t progress_func)
+wimlib_open_wim_with_progress(const tchar *wimfile, int open_flags,
+ WIMStruct **wim_ret,
+ wimlib_progress_func_t progfunc, void *progctx)
{
if (open_flags & ~(WIMLIB_OPEN_FLAG_CHECK_INTEGRITY |
WIMLIB_OPEN_FLAG_ERROR_IF_SPLIT |
return WIMLIB_ERR_INVALID_PARAM;
return open_wim_as_WIMStruct(wimfile, open_flags, wim_ret,
- progress_func);
+ progfunc, progctx);
+}
+
+/* API function documented in wimlib.h */
+WIMLIBAPI int
+wimlib_open_wim(const tchar *wimfile, int open_flags, WIMStruct **wim_ret)
+{
+ return wimlib_open_wim_with_progress(wimfile, open_flags, wim_ret,
+ NULL, NULL);
}
/* Checksum all streams that are unhashed (other than the metadata streams),
if (ret)
return ret;
if (in_prepopulate_list(dentry, ctx)) {
- if (ctx->common.progress_func) {
- union wimlib_progress_info info;
+ union wimlib_progress_info info;
- info.wimboot_exclude.path_in_wim = dentry->_full_path;
- info.wimboot_exclude.extraction_path = current_path(ctx);
+ info.wimboot_exclude.path_in_wim = dentry->_full_path;
+ info.wimboot_exclude.extraction_path = current_path(ctx);
- ctx->common.progress_func(WIMLIB_PROGRESS_MSG_WIMBOOT_EXCLUDE,
- &info);
- FREE(dentry->_full_path);
- dentry->_full_path = NULL;
- }
+ ret = call_progress(ctx->common.progfunc,
+ WIMLIB_PROGRESS_MSG_WIMBOOT_EXCLUDE,
+ &info, ctx->common.progctx);
+ FREE(dentry->_full_path);
+ dentry->_full_path = NULL;
+ return ret;
} else {
FREE(dentry->_full_path);
dentry->_full_path = NULL;
return p;
}
-static enum rp_status
+static int
winnt_try_rpfix(u8 *rpbuf, u16 *rpbuflen_p,
u64 capture_root_ino, u64 capture_root_dev,
const wchar_t *path, struct add_image_params *params)
params->progress.scan.cur_path = printable_path(path);
params->progress.scan.symlink_target = print_name0;
- do_capture_progress(params, WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK, NULL);
+ int ret = do_capture_progress(params,
+ WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK,
+ NULL);
+ if (ret)
+ return ret;
return RP_EXCLUDED;
}
* Path to the reparse point file.
* @params:
* Capture parameters. add_flags, capture_root_ino, capture_root_dev,
- * progress_func, and progress are used.
+ * progfunc, progctx, and progress are used.
* @rpbuf:
* Buffer of length at least REPARSE_POINT_MAX_SIZE bytes into which the
* reparse point buffer will be loaded.
out_progress:
params->progress.scan.cur_path = printable_path(full_path);
if (likely(root))
- do_capture_progress(params, WIMLIB_SCAN_DENTRY_OK, inode);
+ ret = do_capture_progress(params, WIMLIB_SCAN_DENTRY_OK, inode);
else
- do_capture_progress(params, WIMLIB_SCAN_DENTRY_EXCLUDED, NULL);
+ ret = do_capture_progress(params, WIMLIB_SCAN_DENTRY_EXCLUDED, NULL);
out:
if (likely(h != INVALID_HANDLE_VALUE))
(*func_NtClose)(h);
#include "wimlib/integrity.h"
#include "wimlib/lookup_table.h"
#include "wimlib/metadata.h"
+#include "wimlib/progress.h"
#include "wimlib/resource.h"
#ifdef __WIN32__
# include "wimlib/win32.h" /* win32_rename_replacement() */
}
struct write_streams_progress_data {
- wimlib_progress_func_t progress_func;
+ wimlib_progress_func_t progfunc;
+ void *progctx;
union wimlib_progress_info progress;
uint64_t next_progress;
};
-static void
+static int
do_write_streams_progress(struct write_streams_progress_data *progress_data,
struct wim_lookup_table_entry *cur_stream,
u64 complete_size,
bool discarded)
{
union wimlib_progress_info *progress = &progress_data->progress;
+ int ret;
if (discarded) {
progress->write_streams.total_bytes -= complete_size;
progress->write_streams.completed_streams += complete_count;
}
- if (progress_data->progress_func
- && (progress->write_streams.completed_bytes >= progress_data->next_progress))
+ if (progress->write_streams.completed_bytes >= progress_data->next_progress)
{
- progress_data->progress_func(WIMLIB_PROGRESS_MSG_WRITE_STREAMS,
- progress);
+ ret = call_progress(progress_data->progfunc,
+ WIMLIB_PROGRESS_MSG_WRITE_STREAMS,
+ progress,
+ progress_data->progctx);
+ if (ret)
+ return ret;
+
if (progress_data->next_progress == progress->write_streams.total_bytes) {
progress_data->next_progress = ~(uint64_t)0;
} else {
progress->write_streams.total_bytes / 100);
}
}
+ return 0;
}
struct write_streams_ctx {
* duplicate stream in the former case. */
DEBUG("Discarding duplicate stream of "
"length %"PRIu64, lte->size);
- do_write_streams_progress(&ctx->progress_data,
- lte, lte->size,
- 1, true);
+ ret = do_write_streams_progress(&ctx->progress_data,
+ lte, lte->size,
+ 1, true);
list_del(<e->write_streams_list);
list_del(<e->lookup_table_list);
if (lte_new->will_be_in_output_wim)
if (ctx->write_resource_flags & WRITE_RESOURCE_FLAG_PACK_STREAMS)
ctx->cur_write_res_size -= lte->size;
free_lookup_table_entry(lte);
+ if (ret)
+ return ret;
return BEGIN_STREAM_STATUS_SKIP_STREAM;
} else {
/* The duplicate stream can validly be written,
}
}
- do_write_streams_progress(&ctx->progress_data, lte,
- completed_size, completed_stream_count,
- false);
-
- return 0;
+ return do_write_streams_progress(&ctx->progress_data, lte,
+ completed_size, completed_stream_count,
+ false);
error:
ERROR_WITH_ERRNO("Write error");
return ret;
lte->rspec->raw_copy_ok = 0;
}
- do_write_streams_progress(progress_data, lte, lte->size,
- 1, false);
+ ret = do_write_streams_progress(progress_data, lte, lte->size,
+ 1, false);
+ if (ret)
+ return ret;
}
return 0;
}
* no streams are hard-filtered or no streams are unhashed, this parameter
* can be NULL.
*
- * @progress_func
- * If non-NULL, a progress function that will be called periodically with
- * WIMLIB_PROGRESS_MSG_WRITE_STREAMS messages. Note that on-the-fly
- * deduplication of unhashed streams may result in the total bytes provided
- * in the progress data to decrease from one message to the next.
- *
* This function will write the streams in @stream_list to resources in
* consecutive positions in the output WIM file, or to a single packed resource
* if WRITE_RESOURCE_FLAG_PACK_STREAMS was specified in @write_resource_flags.
unsigned num_threads,
struct wim_lookup_table *lookup_table,
struct filter_context *filter_ctx,
- wimlib_progress_func_t progress_func)
+ wimlib_progress_func_t progfunc,
+ void *progctx)
{
int ret;
struct write_streams_ctx ctx;
compute_stream_list_stats(stream_list, &ctx);
- ctx.progress_data.progress_func = progress_func;
+ ctx.progress_data.progfunc = progfunc;
+ ctx.progress_data.progctx = progctx;
ctx.num_bytes_to_compress = find_raw_copy_streams(stream_list,
write_resource_flags,
INIT_LIST_HEAD(&ctx.pending_streams);
INIT_LIST_HEAD(&ctx.pack_streams);
- if (ctx.progress_data.progress_func) {
- (*ctx.progress_data.progress_func)(WIMLIB_PROGRESS_MSG_WRITE_STREAMS,
- &ctx.progress_data.progress);
- }
+ ret = call_progress(ctx.progress_data.progfunc,
+ WIMLIB_PROGRESS_MSG_WRITE_STREAMS,
+ &ctx.progress_data.progress,
+ ctx.progress_data.progctx);
+ if (ret)
+ goto out_destroy_context;
if (write_resource_flags & WRITE_RESOURCE_FLAG_PACK_STREAMS) {
ret = begin_write_resource(&ctx, ctx.num_bytes_to_compress);
struct list_head *stream_list,
int write_flags,
unsigned num_threads,
- struct filter_context *filter_ctx,
- wimlib_progress_func_t progress_func)
+ struct filter_context *filter_ctx)
{
int out_ctype;
u32 out_chunk_size;
num_threads,
wim->lookup_table,
filter_ctx,
- progress_func);
+ wim->progfunc,
+ wim->progctx);
}
static int
1,
NULL,
NULL,
+ NULL,
NULL);
}
static int
write_wim_streams(WIMStruct *wim, int image, int write_flags,
unsigned num_threads,
- wimlib_progress_func_t progress_func,
struct list_head *stream_list_override,
struct list_head *lookup_table_list_ret)
{
stream_list,
write_flags,
num_threads,
- filter_ctx,
- progress_func);
+ filter_ctx);
}
static int
-write_wim_metadata_resources(WIMStruct *wim, int image, int write_flags,
- wimlib_progress_func_t progress_func)
+write_wim_metadata_resources(WIMStruct *wim, int image, int write_flags)
{
int ret;
int start_image;
DEBUG("Writing metadata resources (offset=%"PRIu64")",
wim->out_fd.offset);
- if (progress_func)
- progress_func(WIMLIB_PROGRESS_MSG_WRITE_METADATA_BEGIN, NULL);
+ ret = call_progress(wim->progfunc,
+ WIMLIB_PROGRESS_MSG_WRITE_METADATA_BEGIN,
+ NULL, wim->progctx);
+ if (ret)
+ return ret;
if (image == WIMLIB_ALL_IMAGES) {
start_image = 1;
if (ret)
return ret;
}
- if (progress_func)
- progress_func(WIMLIB_PROGRESS_MSG_WRITE_METADATA_END, NULL);
- return 0;
+
+ return call_progress(wim->progfunc,
+ WIMLIB_PROGRESS_MSG_WRITE_METADATA_END,
+ NULL, wim->progctx);
}
static int
*/
static int
finish_write(WIMStruct *wim, int image, int write_flags,
- wimlib_progress_func_t progress_func,
struct list_head *lookup_table_list)
{
int ret;
ret = write_integrity_table(wim,
new_lookup_table_end,
- old_lookup_table_end,
- progress_func);
+ old_lookup_table_end);
if (ret)
return ret;
} else {
*/
static int
write_pipable_wim(WIMStruct *wim, int image, int write_flags,
- unsigned num_threads, wimlib_progress_func_t progress_func,
+ unsigned num_threads,
struct list_head *stream_list_override,
struct list_head *lookup_table_list_ret)
{
/* Write metadata resources for the image(s) being included in the
* output WIM. */
- ret = write_wim_metadata_resources(wim, image, write_flags,
- progress_func);
+ ret = write_wim_metadata_resources(wim, image, write_flags);
if (ret)
return ret;
/* Write streams needed for the image(s) being included in the output
* WIM, or streams needed for the split WIM part. */
return write_wim_streams(wim, image, write_flags, num_threads,
- progress_func, stream_list_override,
- lookup_table_list_ret);
+ stream_list_override, lookup_table_list_ret);
/* The lookup table, XML data, and header at end are handled by
* finish_write(). */
int image,
int write_flags,
unsigned num_threads,
- wimlib_progress_func_t progress_func,
unsigned part_number,
unsigned total_parts,
struct list_head *stream_list_override,
DEBUG("Number of threads: autodetect");
else
DEBUG("Number of threads: %u", num_threads);
- DEBUG("Progress function: %s", (progress_func ? "yes" : "no"));
+ DEBUG("Progress function: %s", (wim->progfunc ? "yes" : "no"));
DEBUG("Stream list: %s", (stream_list_override ? "specified" : "autodetect"));
DEBUG("GUID: %s", (write_flags &
WIMLIB_WRITE_FLAG_RETAIN_GUID) ? "retain"
if (!(write_flags & WIMLIB_WRITE_FLAG_PIPABLE)) {
/* Default case: create a normal (non-pipable) WIM. */
ret = write_wim_streams(wim, image, write_flags, num_threads,
- progress_func, stream_list_override,
+ stream_list_override,
&lookup_table_list);
if (ret)
goto out_restore_hdr;
- ret = write_wim_metadata_resources(wim, image, write_flags,
- progress_func);
+ ret = write_wim_metadata_resources(wim, image, write_flags);
if (ret)
goto out_restore_hdr;
} else {
/* Non-default case: create pipable WIM. */
ret = write_pipable_wim(wim, image, write_flags, num_threads,
- progress_func, stream_list_override,
+ stream_list_override,
&lookup_table_list);
if (ret)
goto out_restore_hdr;
/* Write lookup table, XML data, and (optional) integrity table. */
- ret = finish_write(wim, image, write_flags, progress_func,
- &lookup_table_list);
+ ret = finish_write(wim, image, write_flags, &lookup_table_list);
out_restore_hdr:
memcpy(&wim->hdr, &hdr_save, sizeof(struct wim_header));
(void)close_wim_writable(wim, write_flags);
/* Write a standalone WIM to a file or file descriptor. */
static int
write_standalone_wim(WIMStruct *wim, const void *path_or_fd,
- int image, int write_flags, unsigned num_threads,
- wimlib_progress_func_t progress_func)
+ int image, int write_flags, unsigned num_threads)
{
return write_wim_part(wim, path_or_fd, image, write_flags,
- num_threads, progress_func, 1, 1, NULL, NULL);
+ num_threads, 1, 1, NULL, NULL);
}
/* API function documented in wimlib.h */
WIMLIBAPI int
wimlib_write(WIMStruct *wim, const tchar *path,
- int image, int write_flags, unsigned num_threads,
- wimlib_progress_func_t progress_func)
+ int image, int write_flags, unsigned num_threads)
{
if (write_flags & ~WIMLIB_WRITE_MASK_PUBLIC)
return WIMLIB_ERR_INVALID_PARAM;
if (path == NULL || path[0] == T('\0'))
return WIMLIB_ERR_INVALID_PARAM;
- return write_standalone_wim(wim, path, image, write_flags,
- num_threads, progress_func);
+ return write_standalone_wim(wim, path, image, write_flags, num_threads);
}
/* API function documented in wimlib.h */
WIMLIBAPI int
wimlib_write_to_fd(WIMStruct *wim, int fd,
- int image, int write_flags, unsigned num_threads,
- wimlib_progress_func_t progress_func)
+ int image, int write_flags, unsigned num_threads)
{
if (write_flags & ~WIMLIB_WRITE_MASK_PUBLIC)
return WIMLIB_ERR_INVALID_PARAM;
write_flags |= WIMLIB_WRITE_FLAG_FILE_DESCRIPTOR;
- return write_standalone_wim(wim, &fd, image, write_flags,
- num_threads, progress_func);
+ return write_standalone_wim(wim, &fd, image, write_flags, num_threads);
}
static bool
* small amount of space compared to the streams, however.)
*/
static int
-overwrite_wim_inplace(WIMStruct *wim, int write_flags,
- unsigned num_threads,
- wimlib_progress_func_t progress_func)
+overwrite_wim_inplace(WIMStruct *wim, int write_flags, unsigned num_threads)
{
int ret;
off_t old_wim_end;
&stream_list,
write_flags,
num_threads,
- &filter_ctx,
- progress_func);
+ &filter_ctx);
if (ret)
goto out_truncate;
- ret = write_wim_metadata_resources(wim, WIMLIB_ALL_IMAGES,
- write_flags, progress_func);
+ ret = write_wim_metadata_resources(wim, WIMLIB_ALL_IMAGES, write_flags);
if (ret)
goto out_truncate;
write_flags |= WIMLIB_WRITE_FLAG_REUSE_INTEGRITY_TABLE;
ret = finish_write(wim, WIMLIB_ALL_IMAGES, write_flags,
- progress_func, &lookup_table_list);
+ &lookup_table_list);
if (ret)
goto out_truncate;
}
static int
-overwrite_wim_via_tmpfile(WIMStruct *wim, int write_flags,
- unsigned num_threads,
- wimlib_progress_func_t progress_func)
+overwrite_wim_via_tmpfile(WIMStruct *wim, int write_flags, unsigned num_threads)
{
size_t wim_name_len;
int ret;
write_flags |
WIMLIB_WRITE_FLAG_FSYNC |
WIMLIB_WRITE_FLAG_RETAIN_GUID,
- num_threads, progress_func);
+ num_threads);
if (ret) {
tunlink(tmpfile);
return ret;
return WIMLIB_ERR_RENAME;
}
- if (progress_func) {
- union wimlib_progress_info progress;
- progress.rename.from = tmpfile;
- progress.rename.to = wim->filename;
- progress_func(WIMLIB_PROGRESS_MSG_RENAME, &progress);
- }
- return 0;
+ union wimlib_progress_info progress;
+ progress.rename.from = tmpfile;
+ progress.rename.to = wim->filename;
+ return call_progress(wim->progfunc, WIMLIB_PROGRESS_MSG_RENAME,
+ &progress, wim->progctx);
}
/* Determine if the specified WIM file may be updated by appending in-place
/* API function documented in wimlib.h */
WIMLIBAPI int
-wimlib_overwrite(WIMStruct *wim, int write_flags,
- unsigned num_threads,
- wimlib_progress_func_t progress_func)
+wimlib_overwrite(WIMStruct *wim, int write_flags, unsigned num_threads)
{
int ret;
u32 orig_hdr_flags;
return ret;
if (can_overwrite_wim_inplace(wim, write_flags)) {
- ret = overwrite_wim_inplace(wim, write_flags, num_threads,
- progress_func);
+ ret = overwrite_wim_inplace(wim, write_flags, num_threads);
if (ret != WIMLIB_ERR_RESOURCE_ORDER)
return ret;
WARNING("Falling back to re-building entire WIM");
}
- return overwrite_wim_via_tmpfile(wim, write_flags, num_threads,
- progress_func);
+ return overwrite_wim_via_tmpfile(wim, write_flags, num_threads);
}