X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=include%2Fwimlib.h;h=c2c32a8c164712ed6001e788d280676726e48c41;hp=93f7f359416c5672f7aa5c562367c872446c929e;hb=2f1f50993984f88df675f0c3302cf4fa52982f05;hpb=20f3793ebcdaa35e525d206a12c1bdf8ebbe64a5 diff --git a/include/wimlib.h b/include/wimlib.h index 93f7f359..c2c32a8c 100644 --- a/include/wimlib.h +++ b/include/wimlib.h @@ -33,7 +33,7 @@ * * @section sec_intro Introduction * - * This is the documentation for the library interface of wimlib 1.5.3, a C + * This is the documentation for the library interface of wimlib 1.6.1, a C * library for creating, modifying, extracting, and mounting files in the * Windows Imaging Format. This documentation is intended for developers only. * If you have installed wimlib and want to know how to use the @b wimlib-imagex @@ -262,8 +262,12 @@ * Another function, wimlib_extract_files(), is also provided. It can extract * certain files or directories from a WIM image, instead of a full image. * - * A third function, wimlib_extract_image_from_pipe(), allows an image to be - * extracted from a pipable WIM sent over a pipe; see @ref subsec_pipable_wims. + * wimlib_extract_paths() and wimlib_extract_pathlist() allow extracting a set + * of paths from a WIM image in a manner that may be easier to use than + * wimlib_extract_files(), and also allow wildcard patterns. + * + * wimlib_extract_image_from_pipe() allows an image to be extracted from a + * pipable WIM sent over a pipe; see @ref subsec_pipable_wims. * * Note that some details of how image extraction/application works are * documented more fully in the manual pages for wimlib-imagex apply and @@ -343,10 +347,10 @@ #define WIMLIB_MAJOR_VERSION 1 /** Minor version of the library (for example, the 2 in 1.2.5). */ -#define WIMLIB_MINOR_VERSION 5 +#define WIMLIB_MINOR_VERSION 6 /** Patch version of the library (for example, the 5 in 1.2.5). */ -#define WIMLIB_PATCH_VERSION 3 +#define WIMLIB_PATCH_VERSION 1 #ifdef __cplusplus extern "C" { @@ -436,8 +440,8 @@ enum wimlib_progress_msg { * ::wimlib_progress_info.extract. */ WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN = 0, - /** A file or directory tree within a WIM image (not the full image) is - * about to be extracted. @p info will point to + /** One or more file or directory trees within a WIM image (not the full + * image) is about to be extracted. @p info will point to * ::wimlib_progress_info.extract. */ WIMLIB_PROGRESS_MSG_EXTRACT_TREE_BEGIN, @@ -449,8 +453,8 @@ enum wimlib_progress_msg { * extracted. @p info will point to ::wimlib_progress_info.extract. */ WIMLIB_PROGRESS_MSG_EXTRACT_DIR_STRUCTURE_END, - /** The WIM image's files resources are currently being extracted. @p - * info will point to ::wimlib_progress_info.extract. */ + /** File data is currently being extracted. @p info will point to + * ::wimlib_progress_info.extract. */ WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS, /** Starting to read a new part of a split pipable WIM over the pipe. @@ -487,9 +491,8 @@ enum wimlib_progress_msg { * ::wimlib_progress_info.scan. */ WIMLIB_PROGRESS_MSG_SCAN_END, - /** - * File resources are currently being written to the WIM. - * @p info will point to ::wimlib_progress_info.write_streams. */ + /** File resources ("streams") are currently being written to the WIM. + * @p info will point to ::wimlib_progress_info.write_streams. */ WIMLIB_PROGRESS_MSG_WRITE_STREAMS, /** @@ -521,9 +524,7 @@ enum wimlib_progress_msg { * ::wimlib_progress_info.integrity. */ WIMLIB_PROGRESS_MSG_CALC_INTEGRITY, - /** Reserved. (Previously used for WIMLIB_PROGRESS_MSG_JOIN_STREAMS, - * but in wimlib v1.5.0 this was removed to simplify the code and now - * you'll get ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS messages instead.) */ + /** Reserved. */ WIMLIB_PROGRESS_MSG_RESERVED, /** A wimlib_split() operation is in progress, and a new split part is @@ -559,142 +560,255 @@ union wimlib_progress_info { /* N.B. I wanted these to be anonymous structs, but Doxygen won't * document them if they aren't given a name... */ - /** Valid on messages ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS. */ + /** Valid on the message ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS. This is + * the primary message for tracking the progress of writing a WIM file. + */ struct wimlib_progress_info_write_streams { - /** Number of bytes that are going to be written for all the - * streams combined. This is the amount in uncompressed data. - * (The actual number of bytes will be less if the data is being - * written compressed.) */ + /** Total number of uncompressed bytes of stream data being + * written. This can be thought of as the total uncompressed + * size of the files being archived, with some caveats. WIM + * files use single-instance streams, so the size provided here + * only counts distinct streams, except for the following + * exception: the size provided here may include the sizes of + * all newly added (e.g. with wimlib_add_image() streams, + * pending automatic de-duplication during the write operation + * itself. When each such stream de-duplication occurs, this + * number will be decreased by the size of the duplicate stream + * that need not be written. + * + * In the case of a wimlib_overwrite() that the library opted to + * perform in-place, both @p total_streams and @p total_bytes + * will only count the streams actually being written and not + * pre-existing streams in the WIM file. */ uint64_t total_bytes; - /** Number of streams that are going to be written. */ + /** Total number of streams being written. This can be thought + * of as the total number of files being archived, with some + * caveats. In general, a single file or directory may contain + * multiple data streams, each of which will be represented + * separately in this number. Furthermore, WIM files use + * single-instance streams, so the stream count provided here + * only counts distinct streams, except for the following + * exception: the stream count provided here may include newly + * added (e.g. with wimlib_add_image() streams, pending + * automatic de-duplication during the write operation itself. + * When each such stream de-duplication occurs, this number will + * be decreased by 1 to account for the duplicate stream that + * need not be written. */ uint64_t total_streams; - /** Number of uncompressed bytes that have been written so far. - * Will be 0 initially, and equal to @p total_bytes at the end. - * */ + /** Number of uncompressed bytes of stream data that have been + * written so far. This number be 0 initially, and will be + * equal to @p total_bytes at the end of the write operation. + * Note that @p total_bytes (but not @p completed_bytes) may + * decrease throughout the write operation due to the discovery + * of stream duplications. */ uint64_t completed_bytes; - /** Number of streams that have been written. Will be 0 - * initially, and equal to @p total_streams at the end. */ + /** Number of streams that have been written so far. This + * number will be 0 initially, and will be equal to @p + * total_streams at the end of the write operation. Note that + * @p total_streams (but not @p completed_streams) may decrease + * throughout the write operation due to the discovery of stream + * duplications. + * + * For applications that wish to calculate a simple "percent + * complete" for the write operation, it will likely be more + * accurate to calculate the percentage from @p completed_bytes + * and @p total_bytes rather than @p completed_streams and + * @p total_streams because the time for the operation to + * complete is mainly determined by the number of bytes that + * need to be read, compressed, and written, not just the number + * of files being archived. */ uint64_t completed_streams; - /** Number of threads that are being used to compress resources - * (if applicable). */ - unsigned num_threads; + /** Number of threads that are being used to compress streams, + * or 1 if streams are being written uncompressed. */ + uint32_t num_threads; - /** The compression type being used to write the streams; either - * ::WIMLIB_COMPRESSION_TYPE_NONE, - * ::WIMLIB_COMPRESSION_TYPE_XPRESS, or - * ::WIMLIB_COMPRESSION_TYPE_LZX. */ - int compression_type; + /** The compression type being used to write the streams, as one + * of the ::wimlib_compression_type constants. */ + int32_t compression_type; /** Number of split WIM parts from which streams are being * written (may be 0 if irrelevant). */ - unsigned total_parts; + uint32_t total_parts; /** Number of split WIM parts from which streams have been * written (may be 0 if irrelevant). */ - unsigned completed_parts; + uint32_t completed_parts; } write_streams; - /** Valid on messages ::WIMLIB_PROGRESS_MSG_SCAN_BEGIN and - * ::WIMLIB_PROGRESS_MSG_SCAN_END. */ + /** Valid on messages ::WIMLIB_PROGRESS_MSG_SCAN_BEGIN, + * ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY, and + * ::WIMLIB_PROGRESS_MSG_SCAN_END. */ struct wimlib_progress_info_scan { - /** Directory or NTFS volume that is being scanned. */ + /** Top-level directory being scanned; or, when capturing a NTFS + * volume with ::WIMLIB_ADD_FLAG_NTFS, this is instead the path + * to the file or block device that contains the NTFS volume + * being scanned. */ const wimlib_tchar *source; - /** Path to the file or directory that is about to be scanned, - * relative to the root of the image capture or the NTFS volume. - * */ + /** Path to the file (or directory) that has been scanned, valid + * on ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY. When capturing a NTFS + * volume with ::WIMLIB_ADD_FLAG_NTFS, this path will be + * relative to the root of the NTFS volume. */ const wimlib_tchar *cur_path; + /** Dentry scan status, valid on + * ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY. */ enum { - /** File or directory looks okay and will be captured. */ + /** The file looks okay and will be captured. */ WIMLIB_SCAN_DENTRY_OK = 0, - /** File or directory is being excluded from capture due - * to the capture configuration file, or being an - * absolute symbolic link that points outside of the - * capture directory without ::WIMLIB_ADD_FLAG_NORPFIX. - */ + /** File is being excluded from capture due to the + * capture configuration. */ WIMLIB_SCAN_DENTRY_EXCLUDED, - /** File or directory is being excluded from capture due - * to being unsupported (e.g. an encrypted or device - * file). */ + /** File is being excluded from capture due to being + * unsupported (e.g. an encrypted or device file). */ WIMLIB_SCAN_DENTRY_UNSUPPORTED, + + /** The file is an absolute symbolic link or junction + * point and it is being excluded from capture because + * it points outside of the capture directory and + * reparse-point fixups are enabled. (Reparse point + * fixups can be disabled by using the flag + * ::WIMLIB_ADD_FLAG_NORPFIX.) */ + WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK, } status; - /** Target path in the WIM. Only valid on messages - * ::WIMLIB_PROGRESS_MSG_SCAN_BEGIN and - * ::WIMLIB_PROGRESS_MSG_SCAN_END. */ - const wimlib_tchar *wim_target_path; + union { + /** Target path in the WIM image. Only valid on + * messages ::WIMLIB_PROGRESS_MSG_SCAN_BEGIN and + * ::WIMLIB_PROGRESS_MSG_SCAN_END. If capturing a full + * image, this will be the empty string; otherwise it + * will name the place in the WIM image at which the + * directory tree is being added. */ + const wimlib_tchar *wim_target_path; + + /** For ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY and a status + * of @p WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK, this is + * the target of the absolute symbolic link or junction + * point. */ + const wimlib_tchar *symlink_target; + }; /** Number of directories scanned so far, including the root * directory but excluding any unsupported/excluded directories. - * */ + * + * Details: On Windows and in NTFS capture mode, a reparse point + * counts as a directory if and only if it has + * FILE_ATTRIBUTE_DIRECTORY set. Otherwise, a symbolic link + * counts as a directory if and only if when fully dereferenced + * it points to an accessible directory. If a file has multiple + * names (hard links), it is only counted one time. */ uint64_t num_dirs_scanned; /** Number of non-directories scanned so far, excluding any - * unsupported/excluded files. */ + * unsupported/excluded files. + * + * Details: On Windows and in NTFS capture mode, a reparse point + * counts as a non-directory if and only if it does not have + * FILE_ATTRIBUTE_DIRECTORY set. Otherwise, a symbolic link + * counts as a non-directory if and only if when fully + * dereferenced it points to a non-directory or its target is + * inaccessible. If a file has multiple names (hard links), it + * is only counted one time. */ uint64_t num_nondirs_scanned; /** Number of bytes of file data that have been detected so far. - * This data may not actually have been read yet, and it will - * not actually be written to the WIM file until wimlib_write() - * or wimlib_overwrite() has been called. */ + * + * Details: This data may not actually have been read yet, and + * it will not actually be written to the WIM file until + * wimlib_write() or wimlib_overwrite() has been called. Data + * from excluded files is not counted. This number includes + * default file contents as well as named data streams and + * reparse point data. The size of reparse point data is + * tallied after any reparse-point fixups, and in the case of + * capturing a symbolic link on a UNIX-like system, the creation + * of the reparse point data itself. If a file has multiple + * names (hard links), its size(s) are only counted one time. + * On Windows, encrypted files have their encrypted size + * counted, not their unencrypted size; however, compressed + * files have their uncompressed size counted. */ uint64_t num_bytes_scanned; } scan; - /** Valid on messages ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN, + /** Valid on messages + * ::WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN, + * ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN, + * ::WIMLIB_PROGRESS_MSG_EXTRACT_TREE_BEGIN, * ::WIMLIB_PROGRESS_MSG_EXTRACT_DIR_STRUCTURE_BEGIN, * ::WIMLIB_PROGRESS_MSG_EXTRACT_DIR_STRUCTURE_END, - * ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS, and - * ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END. */ + * ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS, + * ::WIMLIB_PROGRESS_MSG_EXTRACT_TREE_END, + * ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END, and + * ::WIMLIB_PROGRESS_MSG_APPLY_TIMESTAMPS. + * + * Note: most of the time of an extraction operation will be spent + * extracting streams, and the application will receive + * ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS during this time. Using @p + * completed_bytes and @p total_bytes, the application can calculate a + * percentage complete. However, note that this message does not, in + * general, actually provide information about which "file" is currently + * being extracted. This is because wimlib, by default, extracts the + * individual data streams in whichever order it determines to be the + * most efficient. */ struct wimlib_progress_info_extract { - /** Number of the image being extracted (1-based). */ + /** Number of the image from which files are being extracted + * (1-based). */ int image; - /** Flags passed to to wimlib_extract_image() */ + /** Extraction flags being used. */ int extract_flags; - /** Full path to the WIM file being extracted. */ + /** Full path to the WIM file from which files are being + * extracted, or @c NULL if the WIMStruct has no associated + * on-disk file. */ const wimlib_tchar *wimfile_name; - /** Name of the image being extracted. */ + /** Name of the image from which files are being extracted, or + * the empty string if the image is unnamed. */ const wimlib_tchar *image_name; - /** Directory or NTFS volume to which the image is being - * extracted. */ + /** Path to the directory or NTFS volume to which the files are + * being extracted. */ const wimlib_tchar *target; /** Reserved. */ - const wimlib_tchar *cur_path; + const wimlib_tchar *reserved; /** Number of bytes of uncompressed data that will be extracted. - * Takes into account hard links (they are not counted for each - * link.) */ + * If a file has multiple names (hard links), its size (or + * sizes, in the case of named data streams) is only counted one + * time. For "reparse points" and symbolic links, the size to + * be extracted is the size of the reparse data buffer. + * + * This number will stay constant throughout the extraction. */ uint64_t total_bytes; - /** Number of bytes that have been written so far. Will be 0 - * initially, and equal to @p total_bytes at the end. */ + /** Number of bytes of uncompressed data that have been + * extracted so far. This initially be 0 and will equal to @p + * total_bytes at the end of the extraction. */ uint64_t completed_bytes; - /** Number of streams that will be extracted. This may more or - * less than the number of "files" to be extracted due to - * special cases (hard links, symbolic links, and alternate data - * streams.) */ + /** Number of (not necessarily unique) streams that will be + * extracted. This may be more or less than the number of + * "files" to be extracted due to hard links as well as + * potentially multiple streams per file (named data streams). + * A "stream" may be the default contents of a file, a named + * data stream, or a reparse data buffer. */ uint64_t num_streams; - /** Path to the root dentry within the WIM for the tree that is - * being extracted. Will be the empty string when extracting a - * full image. */ + /** When extracting files using wimlib_extract_files(), this + * will be the path within the WIM image to the file or + * directory tree currently being extracted. Otherwise, this + * will be the empty string. */ const wimlib_tchar *extract_root_wim_source_path; /** Currently only used for * ::WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN. */ - unsigned part_number; /** Currently only used for @@ -1167,8 +1281,8 @@ typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resour #define WIMLIB_ADD_FLAG_DEREFERENCE 0x00000002 /** Call the progress function with the message - * ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY when each directory or file is starting to - * be scanned, or when a directory or file is being excluded from capture. */ + * ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY when each directory or file has been + * scanned. */ #define WIMLIB_ADD_FLAG_VERBOSE 0x00000004 /** Mark the image being added as the bootable image of the WIM. */ @@ -1177,17 +1291,17 @@ typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resour /** Store the UNIX owner, group, and mode. This is done by adding a special * alternate data stream to each regular file, symbolic link, and directory to * contain this information. Please note that this flag is for convenience - * only; Microsoft's @a imagex.exe will not understand this special information. - * This flag cannot be combined with ::WIMLIB_ADD_FLAG_NTFS. */ + * only; Microsoft's implementation will not understand this special + * information. This flag cannot be combined with ::WIMLIB_ADD_FLAG_NTFS. */ #define WIMLIB_ADD_FLAG_UNIX_DATA 0x00000010 /** Do not capture security descriptors. Only has an effect in NTFS capture - * mode, or in Win32 native builds. */ + * mode, or in Windows native builds. */ #define WIMLIB_ADD_FLAG_NO_ACLS 0x00000020 /** Fail immediately if the full security descriptor of any file or directory - * cannot be accessed. Only has an effect in Win32 native builds. The default - * behavior without this flag is to first try omitting the SACL from the + * cannot be accessed. Only has an effect in Windows native builds. The + * default behavior without this flag is to first try omitting the SACL from the * security descriptor, then to try omitting the security descriptor entirely. * */ #define WIMLIB_ADD_FLAG_STRICT_ACLS 0x00000040 @@ -1382,6 +1496,27 @@ typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resour * performance. */ #define WIMLIB_EXTRACT_FLAG_FILE_ORDER 0x00020000 +/** For wimlib_extract_paths() and wimlib_extract_pathlist() only: Treat the + * paths in the WIM as "glob" patterns which may contain the wildcard characters + * '?' and '*'. The '?' character matches any character except a path + * separator, whereas the '*' character matches zero or more non-path-separator + * characters. Each glob pattern may match zero or more paths in the WIM file. + * If a glob pattern ends in a path separator, it will only match directories + * (including reparse points with FILE_ATTRIBUTE_DIRECTORY set). By default, if + * a glob pattern does not match any files, a warning but not an error will be + * issued, even if the glob pattern did not actually contain wildcard + * characters. Use ::WIMLIB_EXTRACT_FLAG_STRICT_GLOB to get an error instead. + */ +#define WIMLIB_EXTRACT_FLAG_GLOB_PATHS 0x00040000 + +/** In combination with ::WIMLIB_EXTRACT_FLAG_GLOB_PATHS, causes an error + * (::WIMLIB_ERR_PATH_DOES_NOT_EXIST) rather than a warning to be issued when + * one of the provided globs did not match a file. */ +#define WIMLIB_EXTRACT_FLAG_STRICT_GLOB 0x00080000 + +/** Do not extract Windows file attributes such as readonly, hidden, etc. */ +#define WIMLIB_EXTRACT_FLAG_NO_ATTRIBUTES 0x00100000 + /** @} */ /** @ingroup G_mounting_wim_images * @{ */ @@ -1590,6 +1725,14 @@ typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resour */ #define WIMLIB_INIT_FLAG_STRICT_APPLY_PRIVILEGES 0x00000008 +/** Default to interpreting WIM paths case sensitively (default on UNIX-like + * systems). */ +#define WIMLIB_INIT_FLAG_DEFAULT_CASE_SENSITIVE 0x00000010 + +/** Default to interpreting WIM paths case insensitively (default on Windows). + * This does not apply to mounted images. */ +#define WIMLIB_INIT_FLAG_DEFAULT_CASE_INSENSITIVE 0x00000020 + /** @} */ /** @ingroup G_nonstandalone_wims * @{ */ @@ -1785,6 +1928,7 @@ enum wimlib_error_code { WIMLIB_ERR_WIM_IS_READONLY, WIMLIB_ERR_WRITE, WIMLIB_ERR_XML, + WIMLIB_ERR_WIM_IS_ENCRYPTED, }; @@ -1794,6 +1938,8 @@ enum wimlib_error_code { /** Used to specify all images in the WIM. */ #define WIMLIB_ALL_IMAGES (-1) +/** @} */ + /** * @ingroup G_modifying_wims * @@ -1928,9 +2074,8 @@ wimlib_add_image_multisource(WIMStruct *wim, * images. No on-disk file is created until wimlib_write() is called. * * @param ctype - * The type of compression to be used in the new WIM file. Must be - * ::WIMLIB_COMPRESSION_TYPE_NONE, ::WIMLIB_COMPRESSION_TYPE_LZX, or - * ::WIMLIB_COMPRESSION_TYPE_XPRESS. + * The type of compression to be used in the new WIM file, as one of the + * ::wimlib_compression_type constants. * @param wim_ret * On success, a pointer to an opaque ::WIMStruct for the new WIM file is * written to the memory location pointed to by this paramater. The @@ -1938,8 +2083,7 @@ wimlib_add_image_multisource(WIMStruct *wim, * it. * @return 0 on success; nonzero on error. * @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE - * @p ctype was not ::WIMLIB_COMPRESSION_TYPE_NONE, - * ::WIMLIB_COMPRESSION_TYPE_LZX, or ::WIMLIB_COMPRESSION_TYPE_XPRESS. + * @p ctype was not a supported compression type. * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate needed memory. */ @@ -2328,6 +2472,60 @@ wimlib_extract_image_from_pipe(int pipe_fd, const wimlib_tchar *target, int extract_flags, wimlib_progress_func_t progress_func); +/** + * @ingroup G_extracting_wims + * + * Since wimlib v1.6.0: Similar to wimlib_extract_paths(), but the paths to + * extract from the WIM image are specified in the UTF-8 text file named by @p + * path_list_file which itself contains the list of paths to use, one per line. + * Leading and trailing whitespace, and otherwise empty lines and lines + * beginning with the ';' character are ignored. No quotes are needed as paths + * are otherwise delimited by the newline character. + */ +extern int +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); + +/** + * @ingroup G_extracting_wims + * + * Since wimlib v1.6.0: Similar to wimlib_extract_files(), but the files or + * directories to extract from the WIM image are specified as an array of paths. + * + * Each path will be extracted to a corresponding subdirectory of the @p target + * based on its location in the WIM image. For example, if one of the paths to + * extract is "/Windows/explorer.exe" and the target is "outdir", the file will + * be extracted to "outdir/Windows/explorer.exe". Each path to extract must be + * specified as the absolute path to a directory within the WIM image. + * Separators in the paths to extract may be either forwards or backwards + * slashes, and leading path separators are optional. Symbolic links are not + * dereferenced when interpreting paths to extract. Paths to extract will be + * interpreted either case-sensitively (UNIX default) or case-insensitively + * (Windows default); this can be changed by wimlib_global_init(). + * + * The @p target path, on the other hand, is expected to be a native path. On + * UNIX-like systems it may not contain backslashes, for example. + * + * By default, if any paths to extract do not exist, + * ::WIMLIB_ERR_PATH_DOES_NOT_EXIST is issued. This behavior changes if + * ::WIMLIB_EXTRACT_FLAG_GLOB_PATHS is specified. + * + * With ::WIMLIB_EXTRACT_FLAG_GLOB_PATHS specified in @p extract_flags, this + * function additionally allows paths to be globs using the wildcard characters + * '*' and '?'. + */ +extern int +wimlib_extract_paths(WIMStruct *wim, + int image, + const wimlib_tchar *target, + const wimlib_tchar * const *paths, + size_t num_paths, + int extract_flags, + wimlib_progress_func_t progress_func); + /** * @ingroup G_wim_information * @@ -2375,12 +2573,11 @@ wimlib_free(WIMStruct *wim); * Converts a ::wimlib_compression_type value into a string. * * @param ctype - * ::WIMLIB_COMPRESSION_TYPE_NONE, ::WIMLIB_COMPRESSION_TYPE_LZX, - * ::WIMLIB_COMPRESSION_TYPE_XPRESS, or another value. + * The ::wimlib_compression_type value to convert. * * @return - * A statically allocated string: "None", "LZX", "XPRESS", or "Invalid", - * respectively. + * A statically allocated string naming the compression algorithm, + * such as "None", "LZX", "XPRESS", or "Invalid". */ extern const wimlib_tchar * wimlib_get_compression_type_string(int ctype); @@ -2496,7 +2693,8 @@ wimlib_get_xml_data(WIMStruct *wim, void **buf_ret, size_t *bufsize_ret); * Initialization function for wimlib. Call before using any other wimlib * function except wimlib_set_print_errors(). If not done manually, this * function will be called automatically with @p init_flags set to - * ::WIMLIB_INIT_FLAG_ASSUME_UTF8. + * ::WIMLIB_INIT_FLAG_ASSUME_UTF8. This function does nothing if called again + * after it has already successfully run. * * @param init_flags * Bitwise OR of flags prefixed with WIMLIB_INIT_FLAG. @@ -2802,10 +3000,10 @@ wimlib_mount_image(WIMStruct *wim, * in the integrity table. * @retval ::WIMLIB_ERR_INVALID_CHUNK_SIZE * Resources in @p wim_file are compressed, but the chunk size was invalid - * for the WIM's compression format. + * for the WIM's compression type. * @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE * The header of @p wim_file says that resources in the WIM are compressed, - * but the header flag indicating LZX or XPRESS compression is not set. + * but the header flag for a recognized compression type is not set. * @retval ::WIMLIB_ERR_INVALID_HEADER * The header of @p wim_file was otherwise invalid. * @retval ::WIMLIB_ERR_INVALID_INTEGRITY_TABLE @@ -2813,9 +3011,7 @@ wimlib_mount_image(WIMStruct *wim, * wim_file contains an integrity table, but the integrity table is * invalid. * @retval ::WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY - * The lookup table for the WIM contained duplicate entries that are not - * for metadata resources, or it contained an entry with a SHA1 message - * digest of all 0's. + * The lookup table for the WIM was invalid. * @retval ::WIMLIB_ERR_INVALID_PARAM * @p wim_ret was @c NULL. * @retval ::WIMLIB_ERR_IS_SPLIT_WIM @@ -2832,8 +3028,7 @@ wimlib_mount_image(WIMStruct *wim, * @retval ::WIMLIB_ERR_UNEXPECTED_END_OF_FILE * Unexpected end-of-file while reading data from @p wim_file. * @retval ::WIMLIB_ERR_UNKNOWN_VERSION - * A number other than 0x10d00 is written in the version field of the WIM - * header of @p wim_file. (May be a pre-Vista WIM.) + * The WIM version number was not recognized. (May be a pre-Vista WIM.) * @retval ::WIMLIB_ERR_WIM_IS_READONLY * ::WIMLIB_OPEN_FLAG_WRITE_ACCESS was specified but the WIM file was * considered read-only because of any of the reasons mentioned in the @@ -2954,15 +3149,6 @@ wimlib_print_available_images(const WIMStruct *wim, int image); extern void wimlib_print_header(const WIMStruct *wim) _wimlib_deprecated; -/** - * @ingroup G_wim_information - * - * Deprecated in favor of wimlib_iterate_dir_tree(), which provides the - * information in a way that can be accessed programatically. - */ -extern int -wimlib_print_metadata(WIMStruct *wim, int image) _wimlib_deprecated; - /** * @ingroup G_nonstandalone_wims * @@ -3191,30 +3377,29 @@ wimlib_set_image_descripton(WIMStruct *wim, int image, * Set the compression chunk size of a WIM to use in subsequent calls to * wimlib_write() or wimlib_overwrite(). * - * A compression chunk size will result in a greater compression ratio, but the - * speed of random access to the WIM will be reduced, and the effect of an - * increased compression chunk size is limited by the size of each file being - * compressed. + * For compatibility reasons, using this function is not generally recommended. + * See the documentation for the @c --chunk-size option of wimlib-imagex + * capture for more information. * - * WARNING: Microsoft's software is seemingly incompatible with LZX chunk - * sizes other than 32768. Chunk sizes other than 32768 (for any format) are - * also incompatible with wimlib v1.5.3 and earlier. + * A larger compression chunk size will likely result in a better compression + * ratio, but the speed of random access to the WIM will be reduced. + * Furthermore, the effect of a larger compression chunk size is limited by the + * size of each stream ("file") being compressed. * * @param wim * ::WIMStruct for a WIM. - * @param out_chunk_size + * @param chunk_size * The chunk size (in bytes) to set. The valid chunk sizes are dependent - * on the compression format. The XPRESS compression format supports chunk - * sizes that are powers of 2 with exponents between 15 and 26 inclusively, - * whereas the LZX compression format supports chunk sizes that are powers - * of 2 with exponents between 15 and 21 inclusively. As a special case, - * if @p out_chunk_size is specified as 0, the chunk size is set to the - * default for the currently selected output compression type. + * on the compression format; see the documentation for the @c --chunk-size + * option of wimlib-imagex capture for more information. As a + * special case, if @p chunk_size is specified as 0, the chunk size is set + * to the default for the currently selected output compression type. * * @return 0 on success; nonzero on error. * * @retval ::WIMLIB_ERR_INVALID_CHUNK_SIZE - * @p ctype is not a supported chunk size. + * @p chunk_size is not a supported chunk size for the currently selected + * output compression type. */ extern int wimlib_set_output_chunk_size(WIMStruct *wim, uint32_t chunk_size); @@ -3254,7 +3439,12 @@ wimlib_set_output_compression_type(WIMStruct *wim, int ctype); * @ingroup G_writing_and_overwriting_wims * * Similar to wimlib_set_output_compression_type(), but set the compression type - * for writing packed streams. + * for writing packed streams (solid blocks). + * + * Note: based on testing, WIMGAPI is seemingly only compatible with LZMS + * compression in packed streams. Therefore the use of this function is not + * recommended. Also, with large chunk sizes, LZMS gives the best compression + * ratio among the alternatives anyway. */ extern int wimlib_set_output_pack_compression_type(WIMStruct *wim, int ctype); @@ -3759,10 +3949,7 @@ wimlib_write_to_fd(WIMStruct *wim, * decompressors currently support sliding windows, and there also exist * slightly different variants of these formats that are not supported * unmodified. - */ - -/** - * @ingroup G_compression + * * @{ */ @@ -3821,10 +4008,11 @@ struct wimlib_lzx_compressor_params { uint32_t slow_reserved1 : 31; - /** Matches with length (in bytes) longer than this - * value are immediately taken without spending time on - * minimum-cost measurements. Suggested value: 32. */ - uint32_t num_fast_bytes; + /** Matches with length (in bytes) greater than or equal + * to this value are immediately taken without spending + * time on minimum-cost measurements. Suggested value: + * 32. */ + uint32_t nice_match_length; /** Number of passes to compute a match/literal sequence * for each LZX block. This is for an iterative @@ -3867,6 +4055,42 @@ struct wimlib_lzx_compressor_params { } alg_params; }; +/** LZMS compression parameters that can optionally be passed to + * wimlib_create_compressor() with the compression type + * ::WIMLIB_COMPRESSION_TYPE_LZMS. */ +struct wimlib_lzms_compressor_params { + /** hdr.size Must be set to the size of this structure, in bytes. */ + struct wimlib_compressor_params_header hdr; + + /** Minimum match length to output. This must be at least 2. Suggested + * value: 2 */ + uint32_t min_match_length; + + /** Maximum match length to output. This must be at least @p + * min_match_length. Suggested value: @p UINT32_MAX. */ + uint32_t max_match_length; + + /** Matches with length (in bytes) greater than or equal to this value + * are immediately taken without spending time on minimum-cost + * measurements. The minimum of @p max_match_length and @p + * nice_match_length may not exceed 65536. Suggested value: 32. */ + uint32_t nice_match_length; + + /** Maximum depth to search for matches at each position. Suggested + * value: 50. */ + uint32_t max_search_depth; + + /** Maximum number of potentially good matches to consider at each + * position. Suggested value: 3. */ + uint32_t max_matches_per_pos; + + /** Length of the array for the near-optimal LZ parsing algorithm. This + * must be at least 1. Suggested value: 1024. */ + uint32_t optim_array_length; + + uint64_t reserved2[4]; +}; + /** Opaque compressor handle. */ struct wimlib_compressor; @@ -3888,6 +4112,8 @@ struct wimlib_decompressor; * * @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE * @p ctype was not a supported compression type. + * @retval ::WIMLIB_ERR_INVALID_PARAM + * @p params were invalid. * @retval ::WIMLIB_ERR_NOMEM * Not enough memory to duplicate the parameters (perhaps @c params->size * was invalid). @@ -3896,6 +4122,18 @@ extern int wimlib_set_default_compressor_params(enum wimlib_compression_type ctype, const struct wimlib_compressor_params_header *params); +/** + * Returns the approximate number of bytes needed to allocate a compressor with + * wimlib_create_compressor() for the specified compression type, block size, + * and parameters. @p params may be @c NULL, in which case the current default + * parameters for @p ctype are used. Returns 0 if the compression type or + * parameters are invalid. + */ +extern uint64_t +wimlib_get_compressor_needed_memory(enum wimlib_compression_type ctype, + size_t max_block_size, + const struct wimlib_compressor_params_header *params); + /** * Allocate a compressor for the specified compression type using the specified * parameters. @@ -4100,8 +4338,18 @@ wimlib_xpress_decompress(const void *cdata, unsigned clen, void *udata, unsigned ulen) _wimlib_deprecated; -/** @} */ +/** + * @} + */ + +/** @ingroup G_wim_information + * + * Deprecated and will return ::WIMLIB_ERR_UNSUPPORTED. Use + * wimlib_iterate_dir_tree() instead. */ +extern int +wimlib_print_metadata(WIMStruct *wim, int image) + _wimlib_deprecated; #ifdef __cplusplus