X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fwimlib.h;h=48922f55e32ef9eb4f700b42e8844c1d9dba05dc;hp=0b0f04bf6b045acea1a988f154cfbecf072ee144;hb=143db75c035e6ecaca451ce70a4ed58a01102b43;hpb=7c83ef53090441de11cc78d8d26dc337cd7ac475 diff --git a/src/wimlib.h b/src/wimlib.h index 0b0f04bf..48922f55 100644 --- a/src/wimlib.h +++ b/src/wimlib.h @@ -9,7 +9,7 @@ */ /* - * Copyright (C) 2012 Eric Biggers + * Copyright (C) 2012, 2013 Eric Biggers * * This file is part of wimlib, a library for working with WIM files. * @@ -31,12 +31,19 @@ * * \section intro Introduction * + * This is the documentation for the library interface of wimlib 1.3.3. If you + * have installed wimlib and want to know how to use the @b wimlib-imagex + * program, please see the man pages instead. Also: the actual project page + * where you can download the source code for the library is at https://sourceforge.net/projects/wimlib. + * * wimlib is a C library to read, write, and mount archive files in the Windows - * Imaging Format (WIM files). These files are normally created using the @c - * imagex.exe utility on Windows, but this library provides a free - * implementetion of @c imagex for UNIX-based systems and an API to allow other - * programs to read, write, and mount WIM files. wimlib is comparable to - * Microsoft's WIMGAPI, but was designed independently and is not a clone of it. + * Imaging Format (WIM files). These files are normally created using the + * ImageX (@a imagex.exe) utility on Windows, but this library provides a free + * implementation of ImageX for UNIX-based systems (and, since v1.3.0, for + * Windows systems) and an API to allow other programs to read, write, and mount + * WIM files. wimlib is comparable to Microsoft's WIMGAPI, but was designed + * independently and is not a clone of it. * * \section format WIM files * @@ -75,6 +82,10 @@ * Configuration Data. In addition, a Windows installation can be captured (or * backed up) into a WIM file, and then re-applied later. * + * wimlib v1.3.0 and later also supports NTFS capture and apply in the native + * Windows build, which works slightly differently and relies on native Win32 + * API calls rather than libntfs-3g. + * * \section winpe Windows PE * * A major use for this library is to create customized images of Windows PE, the @@ -113,8 +124,14 @@ * message being printed. * * wimlib is thread-safe as long as different ::WIMStruct's are used, except for - * the fact that wimlib_set_print_errors() and wimlib_set_memory_allocator() - * both apply globally. + * the following exceptions: + * - wimlib_set_print_errors() and wimlib_set_memory_allocator() both apply globally. + * - You also must call wimlib_global_init() in the main thread to avoid any + * race conditions with one-time allocations of memory. + * - wimlib_mount_image(), while it can be used to mount multiple WIMs + * concurrently in the same process, will daemonize the entire process when it + * does so for the first time. This includes changing the working directory + * to the root directory. * * To open an existing WIM, use wimlib_open_wim(). * @@ -125,7 +142,7 @@ * wimlib_add_image(). This can be done with a ::WIMStruct gotten from * wimlib_open_wim() or from wimlib_create_new_wim(). wimlib_add_image() can * also capture a WIM image directly from a NTFS volume if you provide the - * ::WIMLIB_ADD_IMAGE_FLAG_NTFS flag, provided that wimlib was not compiled with + * ::WIMLIB_ADD_FLAG_NTFS flag, provided that wimlib was not compiled with * the --without-ntfs-3g flag. * * To extract an image from a WIM file, call wimlib_extract_image(). You may @@ -158,28 +175,42 @@ * the WIM operation(s) to report on the progress of the operation (for example, * how many bytes have been written so far). * - * \section imagex imagex + * \section imagex wimlib-imagex * - * wimlib comes with a command-line interface, the @b imagex program. It is - * documented with man pages. See its source code (@c programs/imagex.c in - * wimlib's source tree) for an example of how to use wimlib in your program. + * wimlib comes with a command-line interface, the @b wimlib-imagex program. It + * is documented with man pages. This program was originally just called @b + * imagex, but has been changed to @b wimlib-imagex to avoid confusion with + * Microsoft's @a imagex.exe (which would otherwise have exactly the same + * filename on Windows). * * \section mkwinpeimg mkwinpeimg * * wimlib also comes with the mkwinpeimg script, which is documented in a * man page. + * + * \section encodings Locales and character encodings + * + * To support Windows as well as UNIX, wimlib's API typically takes and returns + * strings of ::wimlib_tchar, which are in a platform-dependent encoding. + * + * On Windows, each ::wimlib_tchar is 2 bytes and is the same as a "wchar_t", + * and the encoding is UTF-16LE. + * + * On UNIX, each ::wimlib_tchar is 1 byte and is simply a "char", and the +* encoding is the locale-dependent multibyte encoding. I recommend you set your +* locale to a UTF-8 capable locale to avoid any issues. Also, by default, + * wimlib on UNIX will assume the locale is UTF-8 capable unless you call +* wimlib_global_init() after having set your desired locale. * * \section Limitations * * While wimlib supports the main features of WIM files, wimlib currently has * the following limitations: - * - wimlib cannot be used on MS-Windows. * - There is no way to add, remove, modify, or extract specific files in a WIM * without mounting it, other than by adding, removing, or extracting an * entire image. The FUSE mount feature should be used for this purpose. * - Currently, Microsoft's @a image.exe can create slightly smaller WIM files - * than wimlib when using maximum (LZX) compression because it knows how to - * split up LZX compressed blocks, which is not yet implemented in wimlib. + * than wimlib (~2% or 3% smaller) when using maximum (LZX) compression. * - wimlib is experimental and likely contains bugs; use Microsoft's @a * imagex.exe if you want to make sure your WIM files are made "correctly". * - The old WIM format from Vista pre-releases is not supported. @@ -195,12 +226,16 @@ * script for a similar purpose, however. With regards to adding drivers to * Windows PE, you have the option of putting them anywhere in the Windows PE * image, then loading them after boot using @b drvload.exe. + * - Although wimlib 1.3.0 and later can be used on Windows as well as UNIX, the + * Windows build has some limitations compared to the UNIX build. + * (The differences are documented better in the man pages for + * @b wimlib-imagex than here.) * * \section legal License * * The wimlib library, as well as the programs and scripts distributed with it - * (@b imagex and @b mkwinpeimg), is licensed under the GNU General Public - * License version 3 or later. + * (@b wimlib-imagex and @b mkwinpeimg), is licensed under the GNU General + * Public License version 3 or later. */ #ifndef _WIMLIB_H @@ -211,9 +246,14 @@ #include #include +/** Major version of the library (for example, the 1 in 1.2.5). */ #define WIMLIB_MAJOR_VERSION 1 -#define WIMLIB_MINOR_VERSION 2 -#define WIMLIB_PATCH_VERSION 0 + +/** Minor version of the library (for example, the 2 in 1.2.5). */ +#define WIMLIB_MINOR_VERSION 3 + +/** Patch version of the library (for example, the 5 in 1.2.5). */ +#define WIMLIB_PATCH_VERSION 3 /** * Opaque structure that represents a WIM file. This is an in-memory structure @@ -230,6 +270,13 @@ */ typedef struct WIMStruct WIMStruct; +#ifdef __WIN32__ +typedef wchar_t wimlib_tchar; +#else +/** See \ref encodings */ +typedef char wimlib_tchar; +#endif + /** * Specifies the compression type of a WIM file. */ @@ -255,6 +302,11 @@ enum wimlib_progress_msg { * ::wimlib_progress_info.extract. */ WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN, + /** A file or directory tree within a WIM image (not the full image) is + * about to be extracted. @a info will point to + * ::wimlib_progress_info.extract. */ + WIMLIB_PROGRESS_MSG_EXTRACT_TREE_BEGIN, + /** The directory structure of the WIM image is about to be extracted. * @a info will point to ::wimlib_progress_info.extract. */ WIMLIB_PROGRESS_MSG_EXTRACT_DIR_STRUCTURE_BEGIN, @@ -281,6 +333,11 @@ enum wimlib_progress_msg { * ::wimlib_progress_info.extract. */ WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END, + /** A file or directory tree within a WIM image (not the full image) has + * been successfully extracted. @a info will point to + * ::wimlib_progress_info.extract. */ + WIMLIB_PROGRESS_MSG_EXTRACT_TREE_END, + /** The directory or NTFS volume is about to be scanned to build a tree * of WIM dentries in-memory. @a info will point to * ::wimlib_progress_info.scan. */ @@ -288,7 +345,7 @@ enum wimlib_progress_msg { /** A directory or file is being scanned. @a info will point to * ::wimlib_progress_info.scan, and its @a cur_path member will be - * valid. This message is only sent if ::WIMLIB_ADD_IMAGE_FLAG_VERBOSE + * valid. This message is only sent if ::WIMLIB_ADD_FLAG_VERBOSE * is passed to wimlib_add_image(). */ WIMLIB_PROGRESS_MSG_SCAN_DENTRY, @@ -297,17 +354,17 @@ enum wimlib_progress_msg { * ::wimlib_progress_info.scan. */ WIMLIB_PROGRESS_MSG_SCAN_END, - /** + /** * File resources are currently being written to the WIM. * @a info will point to ::wimlib_progress_info.write_streams. */ WIMLIB_PROGRESS_MSG_WRITE_STREAMS, - /** + /** * The metadata resource for each image is about to be written to the * WIM. @a info will not be valid. */ WIMLIB_PROGRESS_MSG_WRITE_METADATA_BEGIN, - /** + /** * The metadata resource for each image has successfully been writen to * the WIM. @a info will not be valid. */ WIMLIB_PROGRESS_MSG_WRITE_METADATA_END, @@ -383,22 +440,30 @@ union wimlib_progress_info { * ::WIMLIB_COMPRESSION_TYPE_XPRESS, or * ::WIMLIB_COMPRESSION_TYPE_LZX. */ int compression_type; + + /** Library internal use only. */ + uint64_t _private; } write_streams; /** Valid on messages ::WIMLIB_PROGRESS_MSG_SCAN_BEGIN and * ::WIMLIB_PROGRESS_MSG_SCAN_END. */ struct wimlib_progress_info_scan { /** Directory or NTFS volume that is being scanned. */ - const char *source; + 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. * */ - const char *cur_path; + const wimlib_tchar *cur_path; /** True iff @a cur_path is being excluded from the image * capture due to the capture configuration file. */ bool excluded; + + /** 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; } scan; /** Valid on messages ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN, @@ -410,16 +475,22 @@ union wimlib_progress_info { /** Number of the image being extracted (1-based). */ int image; + /** Flags passed to to wimlib_extract_image() */ + int extract_flags; + + /** Full path to the WIM file being extracted. */ + const wimlib_tchar *wimfile_name; + /** Name of the image being extracted. */ - const char *image_name; + const wimlib_tchar *image_name; /** Directory or NTFS volume to which the image is being * extracted. */ - const char *target; + const wimlib_tchar *target; /** Current dentry being extracted. (Valid only if message is * ::WIMLIB_PROGRESS_MSG_EXTRACT_DENTRY.) */ - const char *cur_path; + const wimlib_tchar *cur_path; /** Number of bytes of uncompressed data that will be extracted. * Takes into account hard links (they are not counted for each @@ -436,16 +507,21 @@ union wimlib_progress_info { * special cases (hard links, symbolic links, and alternate data * streams.) */ 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. */ + const wimlib_tchar *extract_root_wim_source_path; } extract; /** Valid on messages ::WIMLIB_PROGRESS_MSG_RENAME. */ struct wimlib_progress_info_rename { /** Name of the temporary file that the WIM was written to. */ - const char *from; + const wimlib_tchar *from; /** Name of the original WIM file to which the temporary file is * being renamed. */ - const char *to; + const wimlib_tchar *to; } rename; /** Valid on messages ::WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY and @@ -473,7 +549,7 @@ union wimlib_progress_info { /** Filename of the WIM (only valid if the message is * ::WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY). */ - const char *filename; + const wimlib_tchar *filename; } integrity; /** Valid on messages ::WIMLIB_PROGRESS_MSG_JOIN_STREAMS. */ @@ -493,9 +569,6 @@ union wimlib_progress_info { /** Number of split WIM parts. */ unsigned total_parts; - - /** Name of the joined WIM file being written. */ - const char *filename; } join; /** Valid on messages ::WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART and @@ -518,7 +591,7 @@ union wimlib_progress_info { /** Name of the split WIM part that is about to be started * (::WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART) or has just been * finished (::WIMLIB_PROGRESS_MSG_SPLIT_END_PART). */ - const char *part_name; + const wimlib_tchar *part_name; } split; }; @@ -534,25 +607,141 @@ union wimlib_progress_info { typedef int (*wimlib_progress_func_t)(enum wimlib_progress_msg msg_type, const union wimlib_progress_info *info); +/** An array of these structures is passed to wimlib_add_image_multisource() to + * specify the sources from which to create a WIM image. */ +struct wimlib_capture_source { + /** Absolute or relative path to a file or directory on the external + * filesystem to be included in the WIM image. */ + wimlib_tchar *fs_source_path; + + /** Destination path in the WIM image. Leading and trailing slashes are + * ignored. The empty string or @c NULL means the root directory of the + * WIM image. */ + wimlib_tchar *wim_target_path; + + /** Reserved; set to 0. */ + long reserved; +}; + +/** Structure that specifies a list of path patterns. */ +struct wimlib_pattern_list { + /** Array of patterns. The patterns may be modified by library code, + * but the @a pats pointer itself will not. See the man page for + * wimlib-imagex capture for more information about allowed + * patterns. */ + wimlib_tchar **pats; + + /** Number of patterns in the @a pats array. */ + size_t num_pats; + + /** Ignored; may be used by the calling code. */ + size_t num_allocated_pats; +}; + +/** A structure that contains lists of wildcards that match paths to treat + * specially when capturing a WIM image. */ +struct wimlib_capture_config { + /** Paths matching any pattern this list are excluded from being + * captured, except if the same path appears in @a + * exclusion_exception_pats. */ + struct wimlib_pattern_list exclusion_pats; + + /** Paths matching any pattern in this list are never excluded from + * being captured. */ + struct wimlib_pattern_list exclusion_exception_pats; + + /** Reserved for future capture configuration options. */ + struct wimlib_pattern_list reserved1; + + /** Reserved for future capture configuration options. */ + struct wimlib_pattern_list reserved2; + + /** Library internal use only. */ + const wimlib_tchar *_prefix; + + /** Library internal use only. */ + size_t _prefix_num_tchars; +}; + /***************************** - * WIMLIB_ADD_IMAGE_FLAG_* * + * WIMLIB_ADD_FLAG_* * *****************************/ -/** Directly capture a NTFS volume rather than a generic directory */ -#define WIMLIB_ADD_IMAGE_FLAG_NTFS 0x00000001 +/** Directly capture a NTFS volume rather than a generic directory. This flag + * cannot be combined with ::WIMLIB_ADD_FLAG_DEREFERENCE or + * ::WIMLIB_ADD_FLAG_UNIX_DATA. */ +#define WIMLIB_ADD_FLAG_NTFS 0x00000001 /** Follow symlinks; archive and dump the files they point to. Cannot be used - * with ::WIMLIB_ADD_IMAGE_FLAG_NTFS. */ -#define WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE 0x00000002 + * with ::WIMLIB_ADD_FLAG_NTFS. */ +#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. */ -#define WIMLIB_ADD_IMAGE_FLAG_VERBOSE 0x00000004 +#define WIMLIB_ADD_FLAG_VERBOSE 0x00000004 /** Mark the image being added as the bootable image of the WIM. */ -#define WIMLIB_ADD_IMAGE_FLAG_BOOT 0x00000008 +#define WIMLIB_ADD_FLAG_BOOT 0x00000008 + +/** 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. */ +#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. */ +#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 + * security descriptor, then to try omitting the security descriptor entirely. + * */ +#define WIMLIB_ADD_FLAG_STRICT_ACLS 0x00000040 + +/** Call the progress function with the message + * ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY when a directory or file is excluded from + * capture. This is a subset of the messages provided by + * ::WIMLIB_ADD_FLAG_VERBOSE. */ +#define WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE 0x00000080 + +/** Reparse-point fixups: Modify absolute symbolic links (or junction points, + * in the case of Windows) that point inside the directory being captured to + * instead be absolute relative to the directory being captured, rather than the + * current root; also exclude absolute symbolic links that point outside the + * directory tree being captured. + * + * Without this flag, the default is to do this if WIM_HDR_FLAG_RP_FIX is set in + * the WIM header or if this is the first image being added. + * WIM_HDR_FLAG_RP_FIX is set if the first image in a WIM is captured with + * reparse point fixups enabled and currently cannot be unset. */ +#define WIMLIB_ADD_FLAG_RPFIX 0x00000100 + +/** Don't do reparse point fixups. The default behavior is described in the + * documentation for ::WIMLIB_ADD_FLAG_RPFIX. */ +#define WIMLIB_ADD_FLAG_NORPFIX 0x00000200 + +#define WIMLIB_ADD_IMAGE_FLAG_NTFS WIMLIB_ADD_FLAG_NTFS +#define WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE WIMLIB_ADD_FLAG_DEREFERENCE +#define WIMLIB_ADD_IMAGE_FLAG_VERBOSE WIMLIB_ADD_FLAG_VERBOSE +#define WIMLIB_ADD_IMAGE_FLAG_BOOT WIMLIB_ADD_FLAG_BOOT +#define WIMLIB_ADD_IMAGE_FLAG_UNIX_DATA WIMLIB_ADD_FLAG_UNIX_DATA +#define WIMLIB_ADD_IMAGE_FLAG_NO_ACLS WIMLIB_ADD_FLAG_NO_ACLS +#define WIMLIB_ADD_IMAGE_FLAG_STRICT_ACLS WIMLIB_ADD_FLAG_STRICT_ACLS +#define WIMLIB_ADD_IMAGE_FLAG_EXCLUDE_VERBOSE WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE +#define WIMLIB_ADD_IMAGE_FLAG_RPFIX WIMLIB_ADD_FLAG_RPFIX +#define WIMLIB_ADD_IMAGE_FLAG_NORPFIX WIMLIB_ADD_FLAG_NORPFIX + +/** Do not issue an error if the path to delete does not exist. */ +#define WIMLIB_DELETE_FLAG_FORCE 0x00000001 + +/** Delete a file or directory tree recursively; if not specified, an error is + * issued if the path to delete is a directory. */ +#define WIMLIB_DELETE_FLAG_RECURSIVE 0x00000002 /****************************** * WIMLIB_EXPORT_FLAG_* * @@ -586,6 +775,35 @@ typedef int (*wimlib_progress_func_t)(enum wimlib_progress_msg msg_type, /** Read the WIM file sequentially while extracting the image. */ #define WIMLIB_EXTRACT_FLAG_SEQUENTIAL 0x00000010 +/** Extract special UNIX data captured with ::WIMLIB_ADD_FLAG_UNIX_DATA. + * Cannot be used with ::WIMLIB_EXTRACT_FLAG_NTFS. */ +#define WIMLIB_EXTRACT_FLAG_UNIX_DATA 0x00000020 + +/** Do not extract security descriptors. Only has an effect in NTFS apply mode, + * or in Win32 native builds. */ +#define WIMLIB_EXTRACT_FLAG_NO_ACLS 0x00000040 + +/** Fail immediately if the full security descriptor of any file or directory + * cannot be set exactly as specified in the WIM file. The default behavior + * without this flag is to fall back to setting the security descriptor with the + * SACL omitted, then only the default inherited security descriptor, if we do + * not have permission to set the desired one. */ +#define WIMLIB_EXTRACT_FLAG_STRICT_ACLS 0x00000080 + +/* Extract equivalent to ::WIMLIB_ADD_FLAG_RPFIX; force reparse-point + * fixups on, so absolute symbolic links or junction points will be fixed to be + * absolute relative to the actual extraction root. Done by default if + * WIM_HDR_FLAG_RP_FIX is set in the WIM header. This flag may only be + * specified when extracting a full image. */ +#define WIMLIB_EXTRACT_FLAG_RPFIX 0x00000100 + +/** Force reparse-point fixups on extraction off, regardless of the state of the + * WIM_HDR_FLAG_RP_FIX flag in the WIM header. */ +#define WIMLIB_EXTRACT_FLAG_NORPFIX 0x00000200 + +/** Extract files to standard output rather than to the filesystem. */ +#define WIMLIB_EXTRACT_FLAG_TO_STDOUT 0x00000400 + /****************************** * WIMLIB_MOUNT_FLAG_* * ******************************/ @@ -607,6 +825,14 @@ typedef int (*wimlib_progress_func_t)(enum wimlib_progress_msg msg_type, * file name, a colon, then the alternate file stream name. */ #define WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_WINDOWS 0x00000010 +/** Use UNIX file owners, groups, and modes if available in the WIM (see + * ::WIMLIB_ADD_FLAG_UNIX_DATA). */ +#define WIMLIB_MOUNT_FLAG_UNIX_DATA 0x00000020 + +/** Allow other users to see the mounted filesystem. (this passes the @c + * allow_other option to FUSE mount) */ +#define WIMLIB_MOUNT_FLAG_ALLOW_OTHER 0x00000040 + /****************************** * WIMLIB_OPEN_FLAG_* * ******************************/ @@ -629,6 +855,12 @@ typedef int (*wimlib_progress_func_t)(enum wimlib_progress_msg msg_type, * discarded. Ignored for read-only mounts. */ #define WIMLIB_UNMOUNT_FLAG_COMMIT 0x00000002 +/** See ::WIMLIB_WRITE_FLAG_REBUILD */ +#define WIMLIB_UNMOUNT_FLAG_REBUILD 0x00000004 + +/** See ::WIMLIB_WRITE_FLAG_RECOMPRESS */ +#define WIMLIB_UNMOUNT_FLAG_RECOMPRESS 0x00000008 + /****************************** * WIMLIB_WRITE_FLAG_* * ******************************/ @@ -648,7 +880,7 @@ typedef int (*wimlib_progress_func_t)(enum wimlib_progress_msg msg_type, /** Call fsync() when the WIM file is closed */ #define WIMLIB_WRITE_FLAG_FSYNC 0x00000008 -/** Specifying this flag overrides the default behavior of wimlib_overwrite() +/* Specifying this flag overrides the default behavior of wimlib_overwrite() * after one or more calls to wimlib_delete_image(), which is to rebuild the * entire WIM. * @@ -659,23 +891,73 @@ typedef int (*wimlib_progress_func_t)(enum wimlib_progress_msg msg_type, * deleting an image in this way. */ #define WIMLIB_WRITE_FLAG_SOFT_DELETE 0x00000010 +/** Assume that strings are represented in UTF-8, even if this is not the + * locale's character encoding. */ +#define WIMLIB_INIT_FLAG_ASSUME_UTF8 0x00000001 + +/** XXX */ +struct wimlib_update_command { + enum { + WIMLIB_UPDATE_OP_ADD = 0, + WIMLIB_UPDATE_OP_DELETE, + WIMLIB_UPDATE_OP_RENAME, + } op; + union { + struct { + wimlib_tchar *fs_source_path; + wimlib_tchar *wim_target_path; + struct wimlib_capture_config *config; + int add_flags; + } add; + struct { + wimlib_tchar *wim_path; + int delete_flags; + } delete; + struct { + wimlib_tchar *wim_source_path; + wimlib_tchar *wim_target_path; + int rename_flags; + } rename; + }; +}; + +/** Specification of a file or directory tree to extract from a WIM image. */ +struct wimlib_extract_command { + /** Path to file or directory tree within the WIM image to extract. It + * must be provided as an absolute path from the root of the WIM image. + * The path separators may be either forward slashes or backslashes. */ + wimlib_tchar *wim_source_path; + + /** Filesystem path to extract the file or directory tree to. */ + wimlib_tchar *fs_dest_path; + + /** Bitwise or of zero or more of the WIMLIB_EXTRACT_FLAG_* flags. */ + int extract_flags; +}; + /** * Possible values of the error code returned by many functions in wimlib. * * See the documentation for each wimlib function to see specifically what error * codes can be returned by a given function, and what they mean. */ +/* Note: these are currently in alphabetic order, but new error codes should be + * added at the end to maintain a compatible ABI, except when it's being broken + * anyway. */ enum wimlib_error_code { WIMLIB_ERR_SUCCESS = 0, WIMLIB_ERR_ALREADY_LOCKED, WIMLIB_ERR_COMPRESSED_LOOKUP_TABLE, WIMLIB_ERR_DECOMPRESSION, WIMLIB_ERR_DELETE_STAGING_DIR, + WIMLIB_ERR_FILESYSTEM_DAEMON_CRASHED, WIMLIB_ERR_FORK, WIMLIB_ERR_FUSE, WIMLIB_ERR_FUSERMOUNT, + WIMLIB_ERR_ICONV_NOT_AVAILABLE, WIMLIB_ERR_IMAGE_COUNT, WIMLIB_ERR_IMAGE_NAME_COLLISION, + WIMLIB_ERR_INSUFFICIENT_PRIVILEGES_TO_EXTRACT, WIMLIB_ERR_INTEGRITY, WIMLIB_ERR_INVALID_CAPTURE_CONFIG, WIMLIB_ERR_INVALID_CHUNK_SIZE, @@ -685,10 +967,18 @@ enum wimlib_error_code { WIMLIB_ERR_INVALID_IMAGE, WIMLIB_ERR_INVALID_INTEGRITY_TABLE, WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY, + WIMLIB_ERR_INVALID_MULTIBYTE_STRING, + WIMLIB_ERR_INVALID_OVERLAY, WIMLIB_ERR_INVALID_PARAM, + WIMLIB_ERR_INVALID_PART_NUMBER, + WIMLIB_ERR_INVALID_REPARSE_DATA, WIMLIB_ERR_INVALID_RESOURCE_HASH, WIMLIB_ERR_INVALID_RESOURCE_SIZE, WIMLIB_ERR_INVALID_SECURITY_DATA, + WIMLIB_ERR_INVALID_UNMOUNT_MESSAGE, + WIMLIB_ERR_INVALID_UTF16_STRING, + WIMLIB_ERR_INVALID_UTF8_STRING, + WIMLIB_ERR_LIBXML_UTF16_HANDLER_NOT_AVAILABLE, WIMLIB_ERR_LINK, WIMLIB_ERR_MKDIR, WIMLIB_ERR_MQUEUE, @@ -699,40 +989,78 @@ enum wimlib_error_code { WIMLIB_ERR_NTFS_3G, WIMLIB_ERR_OPEN, WIMLIB_ERR_OPENDIR, - WIMLIB_ERR_READLINK, WIMLIB_ERR_READ, + WIMLIB_ERR_READLINK, WIMLIB_ERR_RENAME, WIMLIB_ERR_REOPEN, + WIMLIB_ERR_REPARSE_POINT_FIXUP_FAILED, WIMLIB_ERR_RESOURCE_ORDER, WIMLIB_ERR_SPECIAL_FILE, WIMLIB_ERR_SPLIT_INVALID, WIMLIB_ERR_SPLIT_UNSUPPORTED, WIMLIB_ERR_STAT, WIMLIB_ERR_TIMEOUT, + WIMLIB_ERR_UNICODE_STRING_NOT_REPRESENTABLE, WIMLIB_ERR_UNKNOWN_VERSION, WIMLIB_ERR_UNSUPPORTED, + WIMLIB_ERR_VOLUME_LACKS_FEATURES, WIMLIB_ERR_WRITE, WIMLIB_ERR_XML, + WIMLIB_ERR_PATH_DOES_NOT_EXIST, + WIMLIB_ERR_NOT_A_REGULAR_FILE, + WIMLIB_ERR_IS_DIRECTORY, }; -/** Used to indicate that no WIM image or an invalid WIM image. */ +/** Used to indicate no WIM image or an invalid WIM image. */ #define WIMLIB_NO_IMAGE 0 /** Used to specify all images in the WIM. */ #define WIMLIB_ALL_IMAGES (-1) +/** + * Appends an empty image to a WIM file. This empty image will initially + * contain no files or directories, although if written without further + * modifications, a root directory will be created automatically for it. + * + * @param wim + * Pointer to the ::WIMStruct for the WIM file to which the image is to be + * added. + * @param name + * Name to give the new image. + * @param new_idx_ret + * If non-NULL, the index of the newly added image is returned + * in this location. + * + * @return 0 on success; nonzero on failure. The possible error codes are: + * + * @retval ::WIMLIB_ERR_INVALID_PARAM + * @a name was @c NULL or an empty string. + * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED + * @a wim is part of a split WIM. + * @retval ::WIMLIB_ERR_IMAGE_NAME_COLLISION + * There is already an image in @a wim named @a name. + * @retval ::WIMLIB_ERR_NOMEM + * Failed to allocate the memory needed to add the new image. + */ +extern int +wimlib_add_empty_image(WIMStruct *wim, + const wimlib_tchar *name, + int *new_idx_ret); + /** * Adds an image to a WIM file from an on-disk directory tree or NTFS volume. * - * The directory tree is read immediately for the purpose of constructing a - * directory entry tree in-memory. Also, all files are read to calculate their - * SHA1 message digests. However, because the directory tree may contain a very - * large amount of data, the files themselves are not read into memory - * permanently, and instead references to their paths saved. The files are then - * read on-demand if wimlib_write() or wimlib_overwrite() is called. + * The directory tree or NTFS volume is scanned immediately to load the dentry + * tree into memory, and file attributes and symbolic links are read. However, + * actual file data is not read until wimlib_write() or wimlib_overwrite() is + * called. * - * Please note that @b no changes are committed to the underlying WIM file (if + * See the manual page for the @b wimlib-imagex program for more information + * about the "normal" capture mode versus the NTFS capture mode (entered by + * providing the flag ::WIMLIB_ADD_FLAG_NTFS). + * + * Note that @b no changes are committed to the underlying WIM file (if * any) until wimlib_write() or wimlib_overwrite() is called. * * @param wim @@ -744,23 +1072,11 @@ enum wimlib_error_code { * @param name * The name to give the image. This must be non-@c NULL. * @param config - * Pointer to the contents of an image capture configuration file. If @c - * NULL, a default string is used. Please see the manual page for - * imagex capture for more information. - * @param config_len - * Length of the string @a config in bytes. Ignored if @a config is @c - * NULL. - * - * @param add_image_flags - * Bitwise OR of flags prefixed with WIMLIB_ADD_IMAGE_FLAG. If - * ::WIMLIB_ADD_IMAGE_FLAG_BOOT is specified, the image in @a wim that is - * marked as bootable is changed to the one being added. If - * ::WIMLIB_ADD_IMAGE_FLAG_VERBOSE is specified, the name of each file is - * printed as it is scanned or captured. If - * ::WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE is specified, the files or - * directories pointed to by symbolic links are archived rather than the - * symbolic links themselves. - * + * Capture configuration that specifies files, directories, or path globs + * to exclude from being captured. If @c NULL, a dummy configuration where + * no paths are treated specially is used. + * @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. @@ -779,40 +1095,69 @@ enum wimlib_error_code { * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate needed memory. * @retval ::WIMLIB_ERR_NOTDIR - * @a source is not a directory (only if ::WIMLIB_ADD_IMAGE_FLAG_NTFS was - * not specified in @a add_image_flags). + * @a source is not a directory (only if ::WIMLIB_ADD_FLAG_NTFS was + * not specified in @a add_flags). * @retval ::WIMLIB_ERR_NTFS_3G * An error was returned from a libntfs-3g function when the NTFS volume * was being opened, scanned, or closed (only if - * ::WIMLIB_ADD_IMAGE_FLAG_NTFS was specified in @a add_image_flags). + * ::WIMLIB_ADD_FLAG_NTFS was specified in @a add_flags). * @retval ::WIMLIB_ERR_OPEN * Failed to open a file or directory in the directory tree rooted at @a - * source (only if ::WIMLIB_ADD_IMAGE_FLAG_NTFS was not specified in @a - * add_image_flags). + * source (only if ::WIMLIB_ADD_FLAG_NTFS was not specified in @a + * add_flags). * @retval ::WIMLIB_ERR_READ * Failed to read a file in the directory tree rooted at @a source (only if - * ::WIMLIB_ADD_IMAGE_FLAG_NTFS was not specified in @a add_image_flags). + * ::WIMLIB_ADD_FLAG_NTFS was not specified in @a add_flags). * @retval ::WIMLIB_ERR_SPECIAL_FILE * The directory tree rooted at @a source contains a special file that is * not a directory, regular file, or symbolic link. This currently can - * only be returned if ::WIMLIB_ADD_IMAGE_FLAG_NTFS was not specified in @a - * add_image_flags, but it may be returned for unsupported NTFS files in + * only be returned if ::WIMLIB_ADD_FLAG_NTFS was not specified in @a + * add_flags, but it may be returned for unsupported NTFS files in * the future. * @retval ::WIMLIB_ERR_STAT * Failed obtain the metadata for a file or directory in the directory tree - * rooted at @a source (only if ::WIMLIB_ADD_IMAGE_FLAG_NTFS was not - * specified in @a add_image_flags). + * rooted at @a source (only if ::WIMLIB_ADD_FLAG_NTFS was not + * specified in @a add_flags). * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED * @a wim is part of a split WIM. Adding an image to a split WIM is * unsupported. - * @retval ::WIMLIB_ERR_UNSUPPORTED: - * ::WIMLIB_ADD_IMAGE_FLAG_NTFS was specified in @a add_image_flags, but + * @retval ::WIMLIB_ERR_UNSUPPORTED + * ::WIMLIB_ADD_FLAG_NTFS was specified in @a add_flags, but * wimlib was configured with the @c --without-ntfs-3g flag. */ -extern int wimlib_add_image(WIMStruct *wim, const char *source, - const char *name, const char *config, - size_t config_len, int add_image_flags, - wimlib_progress_func_t progress_func); +extern int +wimlib_add_image(WIMStruct *wim, + const wimlib_tchar *source, + const wimlib_tchar *name, + const struct wimlib_capture_config *config, + int add_flags, + wimlib_progress_func_t progress_func); + +/** This function is equivalent to wimlib_add_image() except it allows for + * multiple sources to be combined into a single WIM image. This is done by + * specifying the @a sources and @a num_sources parameters instead of the @a + * source parameter of wimlib_add_image(). The rest of the parameters are the + * same as wimlib_add_image(). See the documentation for wimlib-imagex + * capture for full details on how this mode works. + * + * In addition to the error codes that wimlib_add_image() can return, + * wimlib_add_image_multisource() can return ::WIMLIB_ERR_INVALID_OVERLAY + * when trying to overlay a non-directory on a directory or when otherwise + * trying to overlay multiple conflicting files to the same location in the WIM + * image. It will also return ::WIMLIB_ERR_INVALID_PARAM if + * ::WIMLIB_ADD_FLAG_NTFS was specified in @a add_flags but there + * was not exactly one capture source with the target being the root directory. + * (In this respect, there is no advantage to using + * wimlib_add_image_multisource() instead of wimlib_add_image() when requesting + * NTFS mode.) */ +extern int +wimlib_add_image_multisource(WIMStruct *w, + const struct wimlib_capture_source *sources, + size_t num_sources, + const wimlib_tchar *name, + const struct wimlib_capture_config *config, + int add_flags, + wimlib_progress_func_t progress_func); /** * Creates a ::WIMStruct for a new WIM file. @@ -836,7 +1181,8 @@ extern int wimlib_add_image(WIMStruct *wim, const char *source, * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate needed memory. */ -extern int wimlib_create_new_wim(int ctype, WIMStruct **wim_ret); +extern int +wimlib_create_new_wim(int ctype, WIMStruct **wim_ret); /** * Deletes an image, or all images, from a WIM file. @@ -879,7 +1225,8 @@ extern int wimlib_create_new_wim(int ctype, WIMStruct **wim_ret); * @a wim is part of a split WIM. Deleting an image from a split WIM is * unsupported. */ -extern int wimlib_delete_image(WIMStruct *wim, int image); +extern int +wimlib_delete_image(WIMStruct *wim, int image); /** * Exports an image, or all the images, from a WIM file, into another WIM file. @@ -970,8 +1317,7 @@ extern int wimlib_delete_image(WIMStruct *wim, int image); * ::WIMLIB_ALL_IMAGES, @a src_wim contains multiple images, and no images in * @a src_wim are marked as bootable; or @a dest_name and/or @a * dest_description were non-NULL, @a src_image was - * ::WIMLIB_ALL_IMAGES, and @a src_wim contains multiple images; or @a src_wim - * or @a dest_wim was @c NULL. + * ::WIMLIB_ALL_IMAGES, and @a src_wim contains multiple images. * @retval ::WIMLIB_ERR_INVALID_RESOURCE_SIZE * The metadata resource for @a src_image in @a src_wim is invalid. * @retval ::WIMLIB_ERR_INVALID_SECURITY_DATA @@ -989,20 +1335,95 @@ extern int wimlib_delete_image(WIMStruct *wim, int image); * @a dest_wim is part of a split WIM. Exporting an image to a split WIM * is unsupported. */ -extern int wimlib_export_image(WIMStruct *src_wim, int src_image, - WIMStruct *dest_wim, const char *dest_name, - const char *dest_description, int export_flags, - WIMStruct **additional_swms, - unsigned num_additional_swms, - wimlib_progress_func_t progress_func); +extern int +wimlib_export_image(WIMStruct *src_wim, int src_image, + WIMStruct *dest_wim, + const wimlib_tchar *dest_name, + const wimlib_tchar *dest_description, + int export_flags, + WIMStruct **additional_swms, + unsigned num_additional_swms, + wimlib_progress_func_t progress_func); + +/** + * Extract zero or more files or directory trees from a WIM image. + * + * This generalizes the single-image extraction functionality of + * wimlib_extract_image() to allow extracting only the specified subsets of the + * image. + * + * @param wim + * Pointer to the ::WIMStruct for a standalone WIM file, or part 1 of a + * split WIM. + * + * @param image + * The 1-based number of the image in @a wim from which the files or + * directory trees are to be extracted. It cannot be ::WIMLIB_ALL_IMAGES. + * + * @param default_extract_flags + * Default extraction flags; the behavior shall be as if these flags had + * been specified in the ::wimlib_extract_command.extract_flags member in + * each extraction command, in combination with any flags already present. + * + * @param cmds + * An array of ::wimlib_extract_command structures that specifies the + * extractions to perform. + * + * @param num_cmds + * Number of commands in the @a cmds array. + * + * @param additional_swms + * Array of pointers to the ::WIMStruct for each additional part in the + * split WIM. Ignored if @a num_additional_swms is 0. The pointers do not + * need to be in any particular order, but they must include all parts of + * the split WIM other than the first part, which must be provided in the + * @a wim parameter. + * + * @param num_additional_swms + * Number of additional WIM parts provided in the @a additional_swms array. + * This number should be one less than the total number of parts in the + * split WIM. Set to 0 if the WIM is a standalone WIM. + * + * @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. The possible error codes include + * those documented as returned by wimlib_extract_image() as well as the + * following additional error codes: + * + * @retval ::WIMLIB_ERR_PATH_DOES_NOT_EXIST + * The ::wimlib_extract_command.wim_source_path member in one of the + * extract commands did not exist in the WIM. + * @retval ::WIMLIB_ERR_NOT_A_REGULAR_FILE + * ::WIMLIB_EXTRACT_FLAG_TO_STDOUT was specified for an extraction command + * in which ::wimlib_extract_command.wim_source_path existed but was not a + * regular file or directory. + * @retval ::WIMLIB_ERR_INVALID_PARAM + * ::WIMLIB_EXTRACT_FLAG_HARDLINK or ::WIMLIB_EXTRACT_FLAG_SYMLINK was + * specified for some commands but not all; or + * ::wimlib_extract_command.fs_dest_path was @c NULL or the empty string + * for one or more commands; or ::WIMLIB_EXTRACT_FLAG_RPFIX was specified + * for a command in which ::wimlib_extract_command.wim_source_path did not + * specify the root directory of the WIM image. + */ +extern int +wimlib_extract_files(WIMStruct *wim, + int image, + int default_extract_flags, + const struct wimlib_extract_command *cmds, + size_t num_cmds, + WIMStruct **additional_swms, + unsigned num_additional_swms, + wimlib_progress_func_t progress_func); /** * Extracts an image, or all images, from a standalone or split WIM file to a * directory or a NTFS volume. * - * Please see the manual page for the @c imagex program for more information - * about the "normal" extraction mode versus the NTFS extraction mode - * (entered by providing flag ::WIMLIB_EXTRACT_FLAG_NTFS). + * Please see the manual page for the @c wimlib-imagex program for more + * information about the "normal" extraction mode versus the NTFS extraction + * mode (entered by providing flag ::WIMLIB_EXTRACT_FLAG_NTFS). * * Extraction is done with one thread. * @@ -1073,12 +1494,14 @@ extern int wimlib_export_image(WIMStruct *src_wim, int src_image, * A directory entry in the metadata resource for @a image in @a wim is * invalid. * @retval ::WIMLIB_ERR_INVALID_PARAM - * @a wim was @c NULL, or @a target was @c NULL, or both - * ::WIMLIB_EXTRACT_FLAG_HARDLINK and ::WIMLIB_EXTRACT_FLAG_SYMLINK were - * specified in @a extract_flags, or both ::WIMLIB_EXTRACT_FLAG_NTFS and - * either ::WIMLIB_EXTRACT_FLAG_HARDLINK or ::WIMLIB_EXTRACT_FLAG_SYMLINK - * were specified in @a extract_flags, or ::WIMLIB_EXTRACT_FLAG_NTFS was - * specified in @a extract_flags and @a image was ::WIMLIB_ALL_IMAGES. + * @a target was @c NULL, or both ::WIMLIB_EXTRACT_FLAG_HARDLINK and + * ::WIMLIB_EXTRACT_FLAG_SYMLINK were specified in @a extract_flags; or + * both ::WIMLIB_EXTRACT_FLAG_NTFS and either + * ::WIMLIB_EXTRACT_FLAG_HARDLINK or ::WIMLIB_EXTRACT_FLAG_SYMLINK were + * specified in @a extract_flags; or ::WIMLIB_EXTRACT_FLAG_NTFS was + * specified in @a extract_flags and @a image was ::WIMLIB_ALL_IMAGES; or + * both ::WIMLIB_EXTRACT_FLAG_NTFS and ::WIMLIB_EXTRACT_FLAG_UNIX_DATA were + * specified in @a extract_flag. * @retval ::WIMLIB_ERR_INVALID_RESOURCE_HASH * The SHA1 message digest of an extracted stream did not match the SHA1 * message digest given in the WIM file. @@ -1116,11 +1539,13 @@ extern int wimlib_export_image(WIMStruct *src_wim, int src_image, * Failed to write a file being extracted (only if * ::WIMLIB_EXTRACT_FLAG_NTFS was not specified in @a extract_flags). */ -extern int wimlib_extract_image(WIMStruct *wim, int image, - const char *target, int extract_flags, - WIMStruct **additional_swms, - unsigned num_additional_swms, - wimlib_progress_func_t progress_func); +extern int +wimlib_extract_image(WIMStruct *wim, int image, + const wimlib_tchar *target, + int extract_flags, + WIMStruct **additional_swms, + unsigned num_additional_swms, + wimlib_progress_func_t progress_func); /** * Extracts the XML data of a WIM file to a file stream. Every WIM file @@ -1138,7 +1563,8 @@ extern int wimlib_extract_image(WIMStruct *wim, int image, * @retval ::WIMLIB_ERR_INVALID_PARAM * @a wim is not a ::WIMStruct that was created by wimlib_open_wim(). */ -extern int wimlib_extract_xml_data(WIMStruct *wim, FILE *fp); +extern int +wimlib_extract_xml_data(WIMStruct *wim, FILE *fp); /** * Frees all memory allocated for a WIMStruct and closes all files associated @@ -1149,7 +1575,8 @@ extern int wimlib_extract_xml_data(WIMStruct *wim, FILE *fp); * * @return This function has no return value. */ -extern void wimlib_free(WIMStruct *wim); +extern void +wimlib_free(WIMStruct *wim); /** * Returns the index of the bootable image of the WIM. @@ -1161,7 +1588,8 @@ extern void wimlib_free(WIMStruct *wim); * 0 if no image is marked as bootable, or the number of the image marked * as bootable (numbered starting at 1). */ -extern int wimlib_get_boot_idx(const WIMStruct *wim); +extern int +wimlib_get_boot_idx(const WIMStruct *wim); /** * Returns the compression type used in the WIM. @@ -1173,7 +1601,8 @@ extern int wimlib_get_boot_idx(const WIMStruct *wim); * ::WIMLIB_COMPRESSION_TYPE_NONE, ::WIMLIB_COMPRESSION_TYPE_LZX, or * ::WIMLIB_COMPRESSION_TYPE_XPRESS. */ -extern int wimlib_get_compression_type(const WIMStruct *wim); +extern int +wimlib_get_compression_type(const WIMStruct *wim); /** * Converts a ::wimlib_compression_type value into a string. @@ -1186,7 +1615,8 @@ extern int wimlib_get_compression_type(const WIMStruct *wim); * A statically allocated string: "None", "LZX", "XPRESS", or "Invalid", * respectively. */ -extern const char *wimlib_get_compression_type_string(int ctype); +extern const wimlib_tchar * +wimlib_get_compression_type_string(int ctype); /** * Converts an error code into a string describing it. @@ -1198,7 +1628,8 @@ extern const char *wimlib_get_compression_type_string(int ctype); * Pointer to a statically allocated string describing the error code, * or @c NULL if the error code is not valid. */ -extern const char *wimlib_get_error_string(enum wimlib_error_code code); +extern const wimlib_tchar * +wimlib_get_error_string(enum wimlib_error_code code); /** * Returns the description of the specified image. @@ -1216,7 +1647,8 @@ extern const char *wimlib_get_error_string(enum wimlib_error_code code); * in addition, the string will become invalid if the description of the * image is changed, the image is deleted, or the ::WIMStruct is destroyed. */ -extern const char *wimlib_get_image_description(const WIMStruct *wim, int image); +extern const wimlib_tchar * +wimlib_get_image_description(const WIMStruct *wim, int image); /** * Returns the name of the specified image. @@ -1237,7 +1669,8 @@ extern const char *wimlib_get_image_description(const WIMStruct *wim, int image) * the WIM to be unnamed, in which case an empty string will be returned * when the corresponding name is requested. */ -extern const char *wimlib_get_image_name(const WIMStruct *wim, int image); +extern const wimlib_tchar * +wimlib_get_image_name(const WIMStruct *wim, int image); /** @@ -1250,7 +1683,8 @@ extern const char *wimlib_get_image_name(const WIMStruct *wim, int image); * @return * The number of images contained in the WIM file. */ -extern int wimlib_get_num_images(const WIMStruct *wim); +extern int +wimlib_get_num_images(const WIMStruct *wim); /** * Returns the part number of a WIM in a split WIM and the total number of parts @@ -1265,7 +1699,41 @@ extern int wimlib_get_num_images(const WIMStruct *wim); * @return * The part number of the WIM (1 for non-split WIMs) */ -extern int wimlib_get_part_number(const WIMStruct *wim, int *total_parts_ret); +extern int +wimlib_get_part_number(const WIMStruct *wim, int *total_parts_ret); + +/** + * Since wimlib 1.2.6: Initialization function for wimlib. This is not + * re-entrant. If you are calling wimlib functions concurrently in different + * threads, then you must call this function serially first. + * + * Since wimlib 1.3.0, you must call this function if the character encoding of + * the current locale is not UTF-8 and you do not want wimlib to assume a UTF-8 + * encoding. + * + * Since wimlib 1.3.2, you must call this function if using the Windows-native + * build of the library so that certain functions can be dynamically loaded from + * system DLLs. + * + * Since wimlib 1.3.3, this function takes the @a init_flags parameter. + * + * @param init_flags + * ::WIMLIB_INIT_FLAG_ASSUME_UTF8 if wimlib should assume that all input + * data, including filenames, are in UTF-8, and that UTF-8 data can be + * directly printed to the console. + * + * @return 0; other error codes may be returned in future releases. + */ +extern int +wimlib_global_init(int init_flags); + +/** + * Since wimlib 1.2.6: Cleanup function for wimlib. This is not re-entrant. + * You are not required to call this function, but it will release any global + * memory allocated by the library. + */ +extern void +wimlib_global_cleanup(); /** * Returns true if the WIM has an integrity table. @@ -1278,8 +1746,8 @@ extern int wimlib_get_part_number(const WIMStruct *wim, int *total_parts_ret); * wimlib_open_wim(), @c false will be returned, even if wimlib_write() has * been called on @a wim with ::WIMLIB_WRITE_FLAG_CHECK_INTEGRITY set. */ -extern bool wimlib_has_integrity_table(const WIMStruct *wim); - +extern bool +wimlib_has_integrity_table(const WIMStruct *wim); /** * Determines if an image name is already used by some image in the WIM. @@ -1294,7 +1762,8 @@ extern bool wimlib_has_integrity_table(const WIMStruct *wim); * if there is no image named @a name in @a wim. If @a name is @c NULL or * the empty string, @c false is returned. */ -extern bool wimlib_image_name_in_use(const WIMStruct *wim, const char *name); +extern bool +wimlib_image_name_in_use(const WIMStruct *wim, const wimlib_tchar *name); /** * Joins a split WIM into a stand-alone one-part WIM. @@ -1333,35 +1802,81 @@ extern bool wimlib_image_name_in_use(const WIMStruct *wim, const char *name); * Note: wimlib_export_image() can provide similar functionality to * wimlib_join(), since it is possible to export all images from a split WIM. */ -extern int wimlib_join(const char **swms, unsigned num_swms, - const char *output_path, int swm_open_flags, - int wim_write_flags, - wimlib_progress_func_t progress_func); +extern int +wimlib_join(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 progress_func); + +/** + * Compress a chunk of a WIM resource using LZX compression. + * + * This function is exported for convenience only and need not be used. + * + * @param chunk + * Uncompressed data of the chunk. + * @param chunk_size + * Size of the uncompressed chunk, in bytes. + * @param out + * Pointer to output buffer of size at least (@a chunk_size - 1) bytes. + * + * @return + * The size of the compressed data written to @a out in bytes, or 0 if the + * data could not be compressed to (@a chunk_size - 1) bytes or fewer. + * + * As a special requirement, the compression code is optimized for the WIM + * format and therefore requires (@a chunk_size <= 32768). + */ +extern unsigned +wimlib_lzx_compress(const void *chunk, unsigned chunk_size, void *out); + +/** + * Decompresses a block of LZX-compressed data as used in the WIM file format. + * + * Note that this will NOT work unmodified for LZX as used in the cabinet + * format, which is not the same as in the WIM format! + * + * This function is exported for convenience only and need not be used. + * + * @param compressed_data + * Pointer to the compressed data. + * + * @param compressed_len + * Length of the compressed data, in bytes. + * + * @param uncompressed_data + * Pointer to the buffer into which to write the uncompressed data. + * + * @param uncompressed_len + * Length of the uncompressed data. It must be 32768 bytes or less. + * + * @return + * 0 on success; non-zero on failure. + */ +extern int +wimlib_lzx_decompress(const void *compressed_data, unsigned compressed_len, + void *uncompressed_data, unsigned uncompressed_len); + /** * Mounts an image in a WIM file on a directory read-only or read-write. * - * A daemon will be forked to service the filesystem, unless - * ::WIMLIB_MOUNT_FLAG_DEBUG is specified in @a mount_flags. In other words, - * this function returns @b before the image is unmounted, and filesystem - * requests are handled by a new thread. This also means that no functions may - * be safely called on @a wim after wimlib_mount_image() has been called on any - * images from it. (@a wim will be freed by the filesystem thread after the - * filesystem is unmounted.) + * Unless ::WIMLIB_MOUNT_FLAG_DEBUG is specified or an early error occurs, the + * process shall be daemonized. * * If the mount is read-write (::WIMLIB_MOUNT_FLAG_READWRITE specified), - * modifications to the WIM are staged in a temporary directory created in the - * process's working directory when this function is called. + * modifications to the WIM are staged in a temporary directory. * * It is safe to mount multiple images from the same WIM file read-only at the - * same time (but different ::WIMStruct's should be used). However, it is @b - * not safe to mount multiple images from the same WIM file read-write at the - * same time. + * same time, but only if different ::WIMStruct's are used. It is @b not safe + * to mount multiple images from the same WIM file read-write at the same time. * * wimlib_mount_image() cannot be used on an image that was exported with * wimlib_export_image() while the dentry trees for both images are still in * memory. In addition, wimlib_mount_image() may not be used to mount an image - * that has just been added with wimlib_add_image(), or unless the WIM has been + * that has just been added with wimlib_add_image(), unless the WIM has been * written and read into a new ::WIMStruct. * * @param wim @@ -1395,10 +1910,18 @@ extern int wimlib_join(const char **swms, unsigned num_swms, * This number should be one less than the total number of parts in the * split WIM. Set to 0 if the WIM is a standalone WIM. * @param staging_dir - * Currently ignored, but may provide a way to specify the staging - * directory in the future. Set to @c NULL. + * If non-NULL, the name of a directory in which the staging directory will + * be created. Ignored if ::WIMLIB_MOUNT_FLAG_READWRITE is not specified + * in @a mount_flags. If left @c NULL, the staging directory is created in + * the same directory as the WIM file that @a wim was originally read from. * * @return 0 on success; nonzero on error. + * + * @retval ::WIMLIB_ERR_ALREADY_LOCKED + * A read-write mount was requested, but an an exclusive advisory lock on + * the on-disk WIM file could not be acquired because another thread or + * process has mounted an image from the WIM read-write or is currently + * modifying the WIM in-place. * @retval ::WIMLIB_ERR_DECOMPRESSION * Could not decompress the metadata resource for @a image in @a wim. * @retval ::WIMLIB_ERR_FUSE @@ -1411,7 +1934,7 @@ extern int wimlib_join(const char **swms, unsigned num_swms, * @retval ::WIMLIB_ERR_INVALID_PARAM * @a image is shared among multiple ::WIMStruct's as a result of a call to * wimlib_export_image(), or @a image has been added with - * wimlib_add_image() or wimlib_add_image_from_ntfs_volume(). + * wimlib_add_image(). * @retval ::WIMLIB_ERR_INVALID_RESOURCE_SIZE * The metadata resource for @a image in @a wim is invalid. * @retval ::WIMLIB_ERR_INVALID_SECURITY_DATA @@ -1435,10 +1958,14 @@ extern int wimlib_join(const char **swms, unsigned num_swms, * The WIM is a split WIM and a read-write mount was requested. We only * support mounting a split WIM read-only. */ -extern int wimlib_mount_image(WIMStruct *wim, int image, const char *dir, - int mount_flags, WIMStruct **additional_swms, - unsigned num_additional_swms, - const char *staging_dir); +extern int +wimlib_mount_image(WIMStruct *wim, + int image, + const wimlib_tchar *dir, + int mount_flags, + WIMStruct **additional_swms, + unsigned num_additional_swms, + const wimlib_tchar *staging_dir); /** * Opens a WIM file and creates a ::WIMStruct for it. @@ -1518,9 +2045,11 @@ extern int wimlib_mount_image(WIMStruct *wim, int image, const char *dir, * @retval ::WIMLIB_ERR_XML * The XML data for @a wim_file is invalid. */ -extern int wimlib_open_wim(const char *wim_file, int open_flags, - WIMStruct **wim_ret, - wimlib_progress_func_t progress_func); +extern int +wimlib_open_wim(const wimlib_tchar *wim_file, + int open_flags, + WIMStruct **wim_ret, + wimlib_progress_func_t progress_func); /** * Overwrites the file that the WIM was originally read from, with changes made. @@ -1560,6 +2089,10 @@ extern int wimlib_open_wim(const char *wim_file, int open_flags, * and while abnormal termination of the program will result in extra data * appended to the original WIM, it should still be a valid WIM. * + * If this function completes successfully, no functions should be called on @a + * wim other than wimlib_free(). You must use wimlib_open_wim() to read the WIM + * file anew. + * * @param wim * Pointer to the ::WIMStruct for the WIM file to write. There may have * been in-memory changes made to it, which are then reflected in the @@ -1577,25 +2110,20 @@ extern int wimlib_open_wim(const char *wim_file, int open_flags, * @return 0 on success; nonzero on error. This function may return any value * returned by wimlib_write() as well as the following error codes: * @retval ::WIMLIB_ERR_ALREADY_LOCKED - * The append-only overwrite mode was going to be used, but an exclusive - * advisory lock on the on-disk WIM file could not be acquired, probably - * because another thread or process was calling wimlib_overwrite() on the - * same underlying on-disk file at the same time. + * The WIM was going to be modifien in-place (with no temporary file), but + * an exclusive advisory lock on the on-disk WIM file could not be acquired + * because another thread or process has mounted an image from the WIM + * read-write or is currently modifying the WIM in-place. * @retval ::WIMLIB_ERR_NO_FILENAME * @a wim corresponds to a WIM created with wimlib_create_new_wim() rather * than a WIM read with wimlib_open_wim(). * @retval ::WIMLIB_ERR_RENAME * The temporary file that the WIM was written to could not be renamed to * the original filename of @a wim. - * @retval ::WIMLIB_ERR_REOPEN - * The WIM was overwritten successfully, but it could not be re-opened - * read-only. Therefore, the resources in the WIM can no longer be - * accessed, so this limits the functions that can be called on @a wim - * before calling wimlib_free(). */ -extern int wimlib_overwrite(WIMStruct *wim, int write_flags, - unsigned num_threads, - wimlib_progress_func_t progress_func); +extern int +wimlib_overwrite(WIMStruct *wim, int write_flags, unsigned num_threads, + wimlib_progress_func_t progress_func); /** * Prints information about one image, or all images, contained in a WIM. @@ -1611,7 +2139,8 @@ extern int wimlib_overwrite(WIMStruct *wim, int write_flags, * printing the information. If @a image is invalid, an error message is * printed. */ -extern void wimlib_print_available_images(const WIMStruct *wim, int image); +extern void +wimlib_print_available_images(const WIMStruct *wim, int image); /** * Prints the full paths to all files contained in an image, or all images, in a @@ -1633,8 +2162,6 @@ extern void wimlib_print_available_images(const WIMStruct *wim, int image); * @retval ::WIMLIB_ERR_INVALID_IMAGE * @a image does not specify a valid image in @a wim, and is not * ::WIMLIB_ALL_IMAGES. - * @retval ::WIMLIB_ERR_INVALID_PARAM - * @a wim was @c NULL. * @retval ::WIMLIB_ERR_INVALID_RESOURCE_SIZE * The metadata resource for one of the specified images is invalid. * @retval ::WIMLIB_ERR_INVALID_SECURITY_DATA @@ -1648,7 +2175,8 @@ extern void wimlib_print_available_images(const WIMStruct *wim, int image); * @a wim was not a standalone WIM and was not the first part of a split * WIM. */ -extern int wimlib_print_files(WIMStruct *wim, int image); +extern int +wimlib_print_files(WIMStruct *wim, int image); /** * Prints detailed information from the header of a WIM file. @@ -1660,7 +2188,8 @@ extern int wimlib_print_files(WIMStruct *wim, int image); * @return This function has no return value. * */ -extern void wimlib_print_header(const WIMStruct *wim); +extern void +wimlib_print_header(const WIMStruct *wim); /** * Prints the lookup table of a WIM file. The lookup table maps SHA1 message @@ -1674,7 +2203,8 @@ extern void wimlib_print_header(const WIMStruct *wim); * * @return This function has no return value. */ -extern void wimlib_print_lookup_table(WIMStruct *wim); +extern void +wimlib_print_lookup_table(WIMStruct *wim); /** * Prints the metadata of the specified image in a WIM file. The metadata @@ -1697,8 +2227,6 @@ extern void wimlib_print_lookup_table(WIMStruct *wim); * @retval ::WIMLIB_ERR_INVALID_IMAGE * @a image does not specify a valid image in @a wim, and is not * ::WIMLIB_ALL_IMAGES. - * @retval ::WIMLIB_ERR_INVALID_PARAM - * @a wim was @c NULL. * @retval ::WIMLIB_ERR_INVALID_RESOURCE_SIZE * The metadata resource for one of the specified images is invalid. * @retval ::WIMLIB_ERR_INVALID_SECURITY_DATA @@ -1712,7 +2240,8 @@ extern void wimlib_print_lookup_table(WIMStruct *wim); * @a wim was not a standalone WIM and was not the first part of a split * WIM. */ -extern int wimlib_print_metadata(WIMStruct *wim, int image); +extern int +wimlib_print_metadata(WIMStruct *wim, int image); /** * Prints some basic information about a WIM file. All information printed by @@ -1725,7 +2254,8 @@ extern int wimlib_print_metadata(WIMStruct *wim, int image); * * @return This function has no return value. */ -extern void wimlib_print_wim_information(const WIMStruct *wim); +extern void +wimlib_print_wim_information(const WIMStruct *wim); /** * Translates a string specifying the name or number of an image in the WIM into @@ -1753,7 +2283,9 @@ extern void wimlib_print_wim_information(const WIMStruct *wim); * the empty string, ::WIMLIB_NO_IMAGE is returned, even if one or more * images in @a wim has no name. */ -extern int wimlib_resolve_image(WIMStruct *wim, const char *image_name_or_num); +extern int +wimlib_resolve_image(WIMStruct *wim, + const wimlib_tchar *image_name_or_num); /** * Sets which image in the WIM is marked as bootable. @@ -1764,8 +2296,6 @@ extern int wimlib_resolve_image(WIMStruct *wim, const char *image_name_or_num); * The number of the image to mark as bootable, or 0 to mark no image as * bootable. * @return 0 on success; nonzero on error. - * @retval ::WIMLIB_ERR_INVALID_PARAM - * @a wim was @c NULL. * @retval ::WIMLIB_ERR_INVALID_IMAGE * @a boot_idx does not specify an existing image in @a wim, and it was not * 0. @@ -1773,7 +2303,8 @@ extern int wimlib_resolve_image(WIMStruct *wim, const char *image_name_or_num); * @a wim is part of a split WIM. We do not support changing the boot * index of a split WIM. */ -extern int wimlib_set_boot_idx(WIMStruct *wim, int boot_idx); +extern int +wimlib_set_boot_idx(WIMStruct *wim, int boot_idx); /** * Changes the description of an image in the WIM. @@ -1791,14 +2322,13 @@ extern int wimlib_set_boot_idx(WIMStruct *wim, int boot_idx); * @return 0 on success; nonzero on error. * @retval ::WIMLIB_ERR_INVALID_IMAGE * @a image does not specify a single existing image in @a wim. - * @retval ::WIMLIB_ERR_INVALID_PARAM - * @a wim was @c NULL. * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate the memory needed to duplicate the @a description * string. */ -extern int wimlib_set_image_descripton(WIMStruct *wim, int image, - const char *description); +extern int +wimlib_set_image_descripton(WIMStruct *wim, int image, + const wimlib_tchar *description); /** * Changes what is written in the \ element in the WIM XML data @@ -1817,12 +2347,11 @@ extern int wimlib_set_image_descripton(WIMStruct *wim, int image, * @return 0 on success; nonzero on error. * @retval ::WIMLIB_ERR_INVALID_IMAGE * @a image does not specify a single existing image in @a wim. - * @retval ::WIMLIB_ERR_INVALID_PARAM - * @a wim was @c NULL. * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate the memory needed to duplicate the @a flags string. */ -extern int wimlib_set_image_flags(WIMStruct *wim, int image, const char *flags); +extern int wimlib_set_image_flags(WIMStruct *wim, int image, + const wimlib_tchar *flags); /** * Changes the name of an image in the WIM. @@ -1834,19 +2363,20 @@ extern int wimlib_set_image_flags(WIMStruct *wim, int image, const char *flags); * @param image * The number of the image for which to change the name. * @param name - * The new name to give the image. It must not a nonempty string. + * The new name to give the image. It must be a nonempty string. * * @return 0 on success; nonzero on error. * @retval ::WIMLIB_ERR_IMAGE_NAME_COLLISION * There is already an image named @a name in @a wim. * @retval ::WIMLIB_ERR_INVALID_PARAM - * @a name was @c NULL or the empty string, or @a wim was @c NULL. + * @a name was @c NULL or the empty string. * @retval ::WIMLIB_ERR_INVALID_IMAGE * @a image does not specify a single existing image in @a wim. * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate the memory needed to duplicate the @a name string. */ -extern int wimlib_set_image_name(WIMStruct *wim, int image, const char *name); +extern int wimlib_set_image_name(WIMStruct *wim, int image, + const wimlib_tchar *name); /** * Set the functions that wimlib uses to allocate and free memory. @@ -1876,9 +2406,10 @@ extern int wimlib_set_image_name(WIMStruct *wim, int image, const char *name); * wimlib was compiled with the @c --without-custom-memory-allocator flag, * so custom memory allocators are unsupported. */ -int wimlib_set_memory_allocator(void *(*malloc_func)(size_t), - void (*free_func)(void *), - void *(*realloc_func)(void *, size_t)); +extern int +wimlib_set_memory_allocator(void *(*malloc_func)(size_t), + void (*free_func)(void *), + void *(*realloc_func)(void *, size_t)); /** * Sets whether wimlib is to print error messages to @c stderr when a function @@ -1900,7 +2431,8 @@ int wimlib_set_memory_allocator(void *(*malloc_func)(size_t), * --without-error-messages option. Therefore, error messages cannot be * shown. */ -extern int wimlib_set_print_errors(bool show_messages); +extern int +wimlib_set_print_errors(bool show_messages); /** * Splits a WIM into multiple parts. @@ -1927,18 +2459,21 @@ extern int wimlib_set_print_errors(bool show_messages); * @return 0 on success; nonzero on error. This function may return any value * returned by wimlib_write() as well as the following error codes: * - * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED: + * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED * @a wim is not part 1 of a stand-alone WIM. * @retval ::WIMLIB_ERR_INVALID_PARAM - * @a w was @c NULL, @a swm_name was @c NULL, or @a part_size was 0. + * @a swm_name was @c NULL, or @a part_size was 0. * * Note: the WIM's uncompressed and compressed resources are not checksummed * when they are copied from the joined WIM to the split WIM parts, nor are * compressed resources re-compressed. */ -extern int wimlib_split(WIMStruct *wim, const char *swm_name, - size_t part_size, int write_flags, - wimlib_progress_func_t progress_func); +extern int +wimlib_split(WIMStruct *wim, + const wimlib_tchar *swm_name, + size_t part_size, + int write_flags, + wimlib_progress_func_t progress_func); /** * Unmounts a WIM image that was mounted using wimlib_mount_image(). @@ -1949,29 +2484,29 @@ extern int wimlib_split(WIMStruct *wim, const char *swm_name, * * To unmount the image, the thread calling this function communicates with the * thread that is managing the mounted WIM image. This function blocks until it - * is known whether the unmount succeeded or failed. (This means until the - * entire WIM has been re-written, in the case of a read-write mounted WIM.) - * - * There is currently a design problem with this function because it is hard to - * know whether the filesystem thread is still working or whether it has crashed - * or has been killed. Currently, a timeout of 600 seconds (so long because - * WIMs can be very large) is implemented so that this function will not wait - * forever before returning failure. + * is known whether the unmount succeeded or failed. In the case of a + * read-write mounted WIM, the unmount is not considered to have succeeded until + * all changes have been saved to the underlying WIM file. * * @param dir * The directory that the WIM image was mounted on. * @param unmount_flags - * Bitwise OR of the flags ::WIMLIB_UNMOUNT_FLAG_CHECK_INTEGRITY and/or - * ::WIMLIB_UNMOUNT_FLAG_COMMIT. Neither of these flags affect read-only + * Bitwise OR of the flags ::WIMLIB_UNMOUNT_FLAG_CHECK_INTEGRITY, + * ::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 - * Currently ignored, but may be used for a progress callback in the - * future. Set to @c NULL. + * If non-NULL, a function that will be called periodically with the + * progress of the current operation. * * @return 0 on success; nonzero on error. + * * @retval ::WIMLIB_ERR_DELETE_STAGING_DIR * The filesystem daemon was unable to remove the staging directory and the * temporary files that it contains. + * @retval ::WIMLIB_ERR_FILESYSTEM_DAEMON_CRASHED + * The filesystem daemon appears to have terminated before sending an exit + * status. * @retval ::WIMLIB_ERR_FORK * Could not @c fork() the process. * @retval ::WIMLIB_ERR_FUSERMOUNT @@ -1986,10 +2521,6 @@ extern int wimlib_split(WIMStruct *wim, const char *swm_name, * @retval ::WIMLIB_ERR_OPEN * The filesystem daemon could not open a temporary file for writing the * new WIM. - * @retval ::WIMLIB_ERR_TIMEOUT - * 600 seconds elapsed while waiting for the filesystem daemon to notify - * the process of its exit status, so the WIM file probably was not written - * successfully. * @retval ::WIMLIB_ERR_READ * A read error occurred when the filesystem daemon tried to a file from * the staging directory @@ -2001,8 +2532,40 @@ extern int wimlib_split(WIMStruct *wim, const char *swm_name, * WIM file, or the filesystem daemon was unable to flush changes that had * been made to files in the staging directory. */ -extern int wimlib_unmount_image(const char *dir, int unmount_flags, - wimlib_progress_func_t progress_func); +extern int +wimlib_unmount_image(const wimlib_tchar *dir, + int unmount_flags, + wimlib_progress_func_t progress_func); + +/** + * Update a WIM image by adding, deleting, and/or renaming files or directories. + * + * @param wim + * Pointer to the ::WIMStruct for the WIM file to update. + * @param image + * The 1-based index of the image in the WIM to update. It cannot be + * ::WIMLIB_ALL_IMAGES. + * @param cmds + * An array of ::wimlib_update_command's that specify the update operations + * to perform. + * @param num_cmds + * Number of commands in @a cmds. + * @param update_flags + * Reserved; must be 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. There are many possible error codes + * (TODO: document them.) + */ +extern int +wimlib_update_image(WIMStruct *wim, + int image, + const struct wimlib_update_command *cmds, + size_t num_cmds, + int update_flags, + wimlib_progress_func_t progress_func); /** * Writes a standalone WIM to a file. @@ -2045,11 +2608,11 @@ extern int wimlib_unmount_image(const char *dir, int unmount_flags, * @a image does not specify a single existing image in @a wim, and is not * ::WIMLIB_ALL_IMAGES. * @retval ::WIMLIB_ERR_INVALID_RESOURCE_HASH - * A file that had previously been scanned for inclusion in the WIM by the - * wimlib_add_image() or wimlib_add_image_from_ntfs_volume() functions was - * concurrently modified, so it failed the SHA1 message digest check. + * A file that had previously been scanned for inclusion in the WIM by + * wimlib_add_image() was concurrently modified, so it failed the SHA1 + * message digest check. * @retval ::WIMLIB_ERR_INVALID_PARAM - * @a wim or @a path was @c NULL. + * @a path was @c NULL. * @retval ::WIMLIB_ERR_INVALID_RESOURCE_SIZE * The metadata resource for @a image in @a wim is invalid. * @retval ::WIMLIB_ERR_INVALID_SECURITY_DATA @@ -2072,8 +2635,27 @@ extern int wimlib_unmount_image(const char *dir, int unmount_flags, * An error occurred when trying to write data to the new WIM file at @a * path. */ -extern int wimlib_write(WIMStruct *wim, const char *path, int image, - int write_flags, unsigned num_threads, - wimlib_progress_func_t progress_func); +extern int +wimlib_write(WIMStruct *wim, + const wimlib_tchar *path, + int image, + int write_flags, + unsigned num_threads, + wimlib_progress_func_t progress_func); + +/** + * This function is equivalent to wimlib_lzx_compress(), but instead compresses + * the data using "XPRESS" compression. + */ +extern unsigned +wimlib_xpress_compress(const void *chunk, unsigned chunk_size, void *out); + +/** + * This function is equivalent to wimlib_lzx_decompress(), but instead assumes + * the data is compressed using "XPRESS" compression. + */ +extern int +wimlib_xpress_decompress(const void *compressed_data, unsigned compressed_len, + void *uncompressed_data, unsigned uncompressed_len); #endif /* _WIMLIB_H */