X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=include%2Fwimlib.h;h=6ab50ce414454e42a3a7b50d7ea6fad810c6f330;hb=38224a9fd97ee047951bb8ab99a089d5c67aebe5;hp=906a15c796cc78a8c2ed062da0e11d419adec3fb;hpb=466646c4f936eb3387b76dcb9a41e7b8cfb98fe2;p=wimlib diff --git a/include/wimlib.h b/include/wimlib.h index 906a15c7..6ab50ce4 100644 --- a/include/wimlib.h +++ b/include/wimlib.h @@ -31,7 +31,7 @@ * * \section intro Introduction * - * This is the documentation for the library interface of wimlib 1.4.0, a C + * This is the documentation for the library interface of wimlib 1.5.0, 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 @@ -90,7 +90,17 @@ * After creating or modifying a WIM file, you can write it to a file using * wimlib_write(). Alternatively, if the WIM was originally read from a file * (using wimlib_open_wim() rather than wimlib_create_new_wim()), you can use - * wimlib_overwrite() to overwrite the original file. + * wimlib_overwrite() to overwrite the original file. Still alternatively, you + * can write a WIM directly to a file descriptor by calling wimlib_write_to_fd() + * instead. + * + * wimlib supports a special "pipable" WIM format (which unfortunately is @b not + * compatible with Microsoft's software). To create a pipable WIM, call + * wimlib_write(), wimlib_write_to_fd(), or wimlib_overwrite() with + * ::WIMLIB_WRITE_FLAG_PIPABLE specified. Pipable WIMs are pipable in both + * directions, so wimlib_write_to_fd() can be used to write a pipable WIM to a + * pipe, and wimlib_extract_image_from_pipe() can be used to apply an image from + * a pipable WIM. * * Please note: merely by calling wimlib_add_image() or many of the other * functions in this library that operate on ::WIMStruct's, you are @b not @@ -156,12 +166,13 @@ #include #include #include +#include /** Major version of the library (for example, the 1 in 1.2.5). */ #define WIMLIB_MAJOR_VERSION 1 /** Minor version of the library (for example, the 2 in 1.2.5). */ -#define WIMLIB_MINOR_VERSION 4 +#define WIMLIB_MINOR_VERSION 5 /** Patch version of the library (for example, the 5 in 1.2.5). */ #define WIMLIB_PATCH_VERSION 0 @@ -191,6 +202,22 @@ typedef wchar_t wimlib_tchar; typedef char wimlib_tchar; #endif +#ifdef __WIN32__ +/** Path separator for WIM paths passed back to progress callbacks. */ +# define WIMLIB_WIM_PATH_SEPARATOR '\\' +# define WIMLIB_WIM_PATH_SEPARATOR_STRING L"\\" +#else +/** Path separator for WIM paths passed back to progress callbacks. */ +# define WIMLIB_WIM_PATH_SEPARATOR '/' +# define WIMLIB_WIM_PATH_SEPARATOR_STRING "/" +#endif + +#ifdef __GNUC__ +# define _wimlib_deprecated __attribute__((deprecated)) +#else +# define _wimlib_deprecated +#endif + /** * Specifies the compression type of a WIM file. */ @@ -214,7 +241,7 @@ enum wimlib_progress_msg { /** A WIM image is about to be extracted. @a info will point to * ::wimlib_progress_info.extract. */ - WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN, + 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. @a info will point to @@ -233,10 +260,8 @@ enum wimlib_progress_msg { * info will point to ::wimlib_progress_info.extract. */ WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS, - /** A file or directory is being extracted. @a info will point to - * ::wimlib_progress_info.extract, and the @a cur_path member will be - * valid. */ - WIMLIB_PROGRESS_MSG_EXTRACT_DENTRY, + /** Reserved. */ + WIMLIB_PROGRESS_MSG_EXTRACT_RESERVED, /** All the WIM files and directories have been extracted, and * timestamps are about to be applied. @a info will point to @@ -302,9 +327,10 @@ enum wimlib_progress_msg { * ::wimlib_progress_info.integrity. */ WIMLIB_PROGRESS_MSG_CALC_INTEGRITY, - /** A wimlib_join() operation is in progress. @a info will point to - * ::wimlib_progress_info.join. */ - WIMLIB_PROGRESS_MSG_JOIN_STREAMS, + /** 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.) */ + WIMLIB_PROGRESS_MSG_RESERVED, /** A wimlib_split() operation is in progress, and a new split part is * about to be started. @a info will point to @@ -314,6 +340,19 @@ enum wimlib_progress_msg { /** A wimlib_split() operation is in progress, and a split part has been * finished. @a info will point to ::wimlib_progress_info.split. */ WIMLIB_PROGRESS_MSG_SPLIT_END_PART, + + /** + * A WIM update command is just about to be executed; @a info will point + * to ::wimlib_progress_info.update. + */ + WIMLIB_PROGRESS_MSG_UPDATE_BEGIN_COMMAND, + + /** + * A WIM update command has just been executed; @a info will point to + * ::wimlib_progress_info.update. + */ + WIMLIB_PROGRESS_MSG_UPDATE_END_COMMAND, + }; /** A pointer to this union is passed to the user-supplied @@ -333,6 +372,7 @@ union wimlib_progress_info { * (The actual number of bytes will be less if the data is being * written compressed.) */ uint64_t total_bytes; + /** Number of streams that are going to be written. */ uint64_t total_streams; @@ -346,7 +386,7 @@ union wimlib_progress_info { uint64_t completed_streams; /** Number of threads that are being used to compress resources - * (if applicable). */ + * (if applicable). */ unsigned num_threads; /** The compression type being used to write the streams; either @@ -355,8 +395,13 @@ union wimlib_progress_info { * ::WIMLIB_COMPRESSION_TYPE_LZX. */ int compression_type; - /** Library internal use only. */ - uint64_t _private; + /** Number of split WIM parts from which streams are being + * written (may be 0 if irrelevant). */ + unsigned total_parts; + + /** Number of split WIM parts from which streams have been + * written (may be 0 if irrelevant). */ + unsigned completed_parts; } write_streams; /** Valid on messages ::WIMLIB_PROGRESS_MSG_SCAN_BEGIN and @@ -402,14 +447,12 @@ union wimlib_progress_info { * extracted. */ const wimlib_tchar *target; - /** Current dentry being extracted. (Valid only if message is - * ::WIMLIB_PROGRESS_MSG_EXTRACT_DENTRY.) */ + /** Reserved. */ 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 - * link.) - * */ + * link.) */ uint64_t total_bytes; /** Number of bytes that have been written so far. Will be 0 @@ -438,6 +481,22 @@ union wimlib_progress_info { const wimlib_tchar *to; } rename; + /** Valid on messages ::WIMLIB_PROGRESS_MSG_UPDATE_BEGIN_COMMAND and + * ::WIMLIB_PROGRESS_MSG_UPDATE_END_COMMAND. */ + struct wimlib_progress_info_update { + /** Pointer to the update command that will be executed or has + * just been executed. */ + const struct wimlib_update_command *command; + + /** Number of update commands that have been completed so far. + */ + size_t completed_commands; + + /** Number of update commands that are being executed as part of + * this call to wimlib_update_image(). */ + size_t total_commands; + } update; + /** Valid on messages ::WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY and * ::WIMLIB_PROGRESS_MSG_CALC_INTEGRITY. */ struct wimlib_progress_info_integrity { @@ -466,25 +525,6 @@ union wimlib_progress_info { const wimlib_tchar *filename; } integrity; - /** Valid on messages ::WIMLIB_PROGRESS_MSG_JOIN_STREAMS. */ - struct wimlib_progress_info_join { - /** Total number of bytes of compressed data contained in all - * the split WIM part's file and metadata resources. */ - uint64_t total_bytes; - - /** Number of bytes that have been copied to the joined WIM so - * far. Will be 0 initially, and equal to @a total_bytes at the - * end. */ - uint64_t completed_bytes; - - /** Number of split WIM parts that have had all their file and - * metadata resources copied over to the joined WIM so far. */ - unsigned completed_parts; - - /** Number of split WIM parts. */ - unsigned total_parts; - } join; - /** Valid on messages ::WIMLIB_PROGRESS_MSG_SPLIT_BEGIN_PART and * ::WIMLIB_PROGRESS_MSG_SPLIT_END_PART. */ struct wimlib_progress_info_split { @@ -502,6 +542,9 @@ union wimlib_progress_info { * finished (::WIMLIB_PROGRESS_MSG_SPLIT_END_PART). */ unsigned cur_part_number; + /** Total number of split WIM parts that are being written. */ + unsigned total_parts; + /** 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). */ @@ -571,12 +614,274 @@ struct wimlib_capture_config { struct wimlib_pattern_list reserved2; /** Library internal use only. */ - const wimlib_tchar *_prefix; + wimlib_tchar *_prefix; /** Library internal use only. */ size_t _prefix_num_tchars; }; +/** Set or unset the WIM header flag that marks it read-only + * (WIM_HDR_FLAG_READONLY in Microsoft's documentation), based on the + * ::wimlib_wim_info.is_marked_readonly member of the @a info parameter. This + * is distinct from basic file permissions; this flag can be set on a WIM file + * that is physically writable. If this flag is set, all further operations to + * modify the WIM will fail, except calling wimlib_overwrite() with + * ::WIMLIB_WRITE_FLAG_IGNORE_READONLY_FLAG specified, which is a loophole that + * allows you to set this flag persistently on the underlying WIM file. + */ +#define WIMLIB_CHANGE_READONLY_FLAG 0x00000001 + +/** Set the GUID (globally unique identifier) of the WIM file to the value + * specified in ::wimlib_wim_info.guid of the @a info parameter. */ +#define WIMLIB_CHANGE_GUID 0x00000002 + +/** Change the bootable image of the WIM to the value specified in + * ::wimlib_wim_info.boot_index of the @a info parameter. */ +#define WIMLIB_CHANGE_BOOT_INDEX 0x00000004 + +/** Change the WIM_HDR_FLAG_RP_FIX flag of the WIM file to the value specified + * in ::wimlib_wim_info.has_rpfix of the @a info parameter. This flag generally + * indicates whether an image in the WIM has been captured with reparse-point + * fixups enabled. wimlib also treats this flag as specifying whether to do + * reparse-point fixups by default when capturing or applying WIM images. */ +#define WIMLIB_CHANGE_RPFIX_FLAG 0x00000008 + +#define WIMLIB_GUID_LEN 16 + +/** General information about a WIM file. */ +struct wimlib_wim_info { + + /** Globally unique identifier for the WIM file. Note: all parts of a + * split WIM should have an identical value in this field. */ + uint8_t guid[WIMLIB_GUID_LEN]; + + /** Number of images in the WIM. */ + uint32_t image_count; + + /** 1-based index of the bootable image in the WIM, or 0 if no image is + * bootable. */ + uint32_t boot_index; + + /** Version of the WIM file. */ + uint32_t wim_version; + + /** Chunk size used for compression. */ + uint32_t chunk_size; + + /** 1-based index of this part within a split WIM, or 1 if the WIM is + * standalone. */ + uint16_t part_number; + + /** Total number of parts in the split WIM, or 1 if the WIM is + * standalone. */ + uint16_t total_parts; + + /** One of the ::wimlib_compression_type values that specifies the + * method used to compress resources in the WIM. */ + int32_t compression_type; + + /** Size of the WIM file in bytes, excluding the XML data and integrity + * table. */ + uint64_t total_bytes; + + /** 1 if the WIM has an integrity table. Note: if the ::WIMStruct was + * created via wimlib_create_new_wim() rather than wimlib_open_wim(), + * this will always be 0, even if the ::WIMStruct was written to + * somewhere by calling wimlib_write() with the + * ::WIMLIB_WRITE_FLAG_CHECK_INTEGRITY flag specified. */ + uint32_t has_integrity_table : 1; + + /** 1 if the ::WIMStruct was created via wimlib_open_wim() rather than + * wimlib_create_new_wim(). */ + uint32_t opened_from_file : 1; + + /** 1 if the WIM is considered readonly for any reason. */ + uint32_t is_readonly : 1; + + /** 1 if reparse-point fixups are supposedly enabled for one or more + * images in the WIM. */ + uint32_t has_rpfix : 1; + + /** 1 if the WIM is marked as read-only. */ + uint32_t is_marked_readonly : 1; + + /** 1 if the WIM is part of a spanned set. */ + uint32_t spanned : 1; + + uint32_t write_in_progress : 1; + uint32_t metadata_only : 1; + uint32_t resource_only : 1; + + /** 1 if the WIM is pipable (see ::WIMLIB_WRITE_FLAG_PIPABLE). */ + uint32_t pipable : 1; + uint32_t reserved_flags : 22; + uint32_t reserved[9]; +}; + +/** Information about a unique resource in the WIM file. + */ +struct wimlib_resource_entry { + /** Uncompressed size of the resource in bytes. */ + uint64_t uncompressed_size; + + /** Compressed size of the resource in bytes. This will be the same as + * @a uncompressed_size if the resource is uncompressed. */ + uint64_t compressed_size; + + /** Offset, in bytes, of this resource from the start of the WIM file. + */ + uint64_t offset; + + /** SHA1 message digest of the resource's uncompressed contents. */ + uint8_t sha1_hash[20]; + + /** Which part number of the split WIM this resource is in. This should + * be the same as the part number provided by wimlib_get_wim_info(). */ + uint32_t part_number; + + /** Number of times this resource is referenced over all WIM images. */ + uint32_t reference_count; + + /** 1 if this resource is compressed. */ + uint32_t is_compressed : 1; + + /** 1 if this resource is a metadata resource rather than a file + * resource. */ + uint32_t is_metadata : 1; + + uint32_t is_free : 1; + uint32_t is_spanned : 1; + uint32_t reserved_flags : 28; + uint64_t reserved[4]; +}; + +/** A stream of a file in the WIM. */ +struct wimlib_stream_entry { + /** Name of the stream, or NULL if the stream is unnamed. */ + const wimlib_tchar *stream_name; + /** Location, size, etc. of the stream within the WIM file. */ + struct wimlib_resource_entry resource; + uint64_t reserved[4]; +}; + +/** Structure passed to the wimlib_iterate_dir_tree() callback function. + * Roughly, the information about a "file" in the WIM--- but really a directory + * entry ("dentry") because hard links are allowed. The hard_link_group_id + * field can be used to distinguish actual file inodes. */ +struct wimlib_dir_entry { + /** Name of the file, or NULL if this file is unnamed (only possible for + * the root directory) */ + const wimlib_tchar *filename; + + /** 8.3 DOS name of this file, or NULL if this file has no such name. + * */ + const wimlib_tchar *dos_name; + + /** Full path to this file within the WIM image. */ + const wimlib_tchar *full_path; + + /** Depth of this directory entry, where 0 is the root, 1 is the root's + * children, ..., etc. */ + size_t depth; + + /** Pointer to the security descriptor for this file, in Windows + * SECURITY_DESCRIPTOR_RELATIVE format, or NULL if this file has no + * security descriptor. */ + const char *security_descriptor; + + /** Length of the above security descriptor. */ + size_t security_descriptor_size; + +#define WIMLIB_FILE_ATTRIBUTE_READONLY 0x00000001 +#define WIMLIB_FILE_ATTRIBUTE_HIDDEN 0x00000002 +#define WIMLIB_FILE_ATTRIBUTE_SYSTEM 0x00000004 +#define WIMLIB_FILE_ATTRIBUTE_DIRECTORY 0x00000010 +#define WIMLIB_FILE_ATTRIBUTE_ARCHIVE 0x00000020 +#define WIMLIB_FILE_ATTRIBUTE_DEVICE 0x00000040 +#define WIMLIB_FILE_ATTRIBUTE_NORMAL 0x00000080 +#define WIMLIB_FILE_ATTRIBUTE_TEMPORARY 0x00000100 +#define WIMLIB_FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 +#define WIMLIB_FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 +#define WIMLIB_FILE_ATTRIBUTE_COMPRESSED 0x00000800 +#define WIMLIB_FILE_ATTRIBUTE_OFFLINE 0x00001000 +#define WIMLIB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 +#define WIMLIB_FILE_ATTRIBUTE_ENCRYPTED 0x00004000 +#define WIMLIB_FILE_ATTRIBUTE_VIRTUAL 0x00010000 + /** File attributes, such as whether the file is a directory or not. + * These are the "standard" Windows FILE_ATTRIBUTE_* values, although in + * wimlib.h they are defined as WIMLIB_FILE_ATTRIBUTE_* for convenience + * on other platforms. */ + uint32_t attributes; + +#define WIMLIB_REPARSE_TAG_RESERVED_ZERO 0x00000000 +#define WIMLIB_REPARSE_TAG_RESERVED_ONE 0x00000001 +#define WIMLIB_REPARSE_TAG_MOUNT_POINT 0xA0000003 +#define WIMLIB_REPARSE_TAG_HSM 0xC0000004 +#define WIMLIB_REPARSE_TAG_HSM2 0x80000006 +#define WIMLIB_REPARSE_TAG_DRIVER_EXTENDER 0x80000005 +#define WIMLIB_REPARSE_TAG_SIS 0x80000007 +#define WIMLIB_REPARSE_TAG_DFS 0x8000000A +#define WIMLIB_REPARSE_TAG_DFSR 0x80000012 +#define WIMLIB_REPARSE_TAG_FILTER_MANAGER 0x8000000B +#define WIMLIB_REPARSE_TAG_SYMLINK 0xA000000C + /** If the file is a reparse point (FILE_ATTRIBUTE_DIRECTORY set in the + * attributes), this will give the reparse tag. This tells you whether + * the reparse point is a symbolic link, junction point, or some other, + * more unusual kind of reparse point. */ + uint32_t reparse_tag; + + /* Number of (hard) links to this file. */ + uint32_t num_links; + + /** Number of named data streams that this file has. Normally 0. */ + uint32_t num_named_streams; + + /** Roughly, the inode number of this file. However, it may be 0 if + * @a num_links == 1. */ + uint64_t hard_link_group_id; + + /** Time this file was created. */ + struct timespec creation_time; + + /** Time this file was last written to. */ + struct timespec last_write_time; + + /** Time this file was last accessed. */ + struct timespec last_access_time; + uint64_t reserved[16]; + + /** Array of streams that make up this file. The first entry will + * always exist and will correspond to the unnamed data stream (default + * file contents), so it will have @a stream_name == @c NULL. There + * will then be @a num_named_streams additional entries that specify the + * named data streams, if any, each of which will have @a stream_name != + * @c NULL. */ + struct wimlib_stream_entry streams[]; +}; + +/** + * Type of a callback function to wimlib_iterate_dir_tree(). Must return 0 on + * success. + */ +typedef int (*wimlib_iterate_dir_tree_callback_t)(const struct wimlib_dir_entry *dentry, + void *user_ctx); + +/** + * Type of a callback function to wimlib_iterate_lookup_table(). Must return 0 + * on success. + */ +typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resource_entry *resource, + void *user_ctx); + +/** For wimlib_iterate_dir_tree(): Iterate recursively on children rather than + * just on the specified path. */ +#define WIMLIB_ITERATE_DIR_TREE_FLAG_RECURSIVE 0x00000001 + +/** For wimlib_iterate_dir_tree(): Don't iterate on the file or directory + * itself; only its children (in the case of a non-empty directory) */ +#define WIMLIB_ITERATE_DIR_TREE_FLAG_CHILDREN 0x00000002 + + /***************************** * WIMLIB_ADD_FLAG_* @@ -684,10 +989,7 @@ struct wimlib_capture_config { * together. Cannot be used with ::WIMLIB_EXTRACT_FLAG_NTFS. */ #define WIMLIB_EXTRACT_FLAG_SYMLINK 0x00000004 -/** Call the progress function with the argument - * ::WIMLIB_PROGRESS_MSG_EXTRACT_DENTRY each time a file or directory is - * extracted. Note: these calls will be interspersed with calls for the message - * ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS. */ +/** This flag no longer does anything but is reserved for future use. */ #define WIMLIB_EXTRACT_FLAG_VERBOSE 0x00000008 /** Read the WIM file sequentially while extracting the image. */ @@ -722,6 +1024,31 @@ struct wimlib_capture_config { /** Extract files to standard output rather than to the filesystem. */ #define WIMLIB_EXTRACT_FLAG_TO_STDOUT 0x00000400 +/** Instead of ignoring files and directories with names that cannot be + * represented on the current platform (note: Windows has more restrictions on + * filenames than UNIX), try to replace characters or append junk to the names + * so that they can be extracted in some form. */ +#define WIMLIB_EXTRACT_FLAG_REPLACE_INVALID_FILENAMES 0x00000800 + +/** On Windows, when there exist two or more files with the same case + * insensitive name but different case sensitive names, try to extract them all + * by appending junk to the end of them, rather than arbitrarily extracting only + * one. */ +#define WIMLIB_EXTRACT_FLAG_ALL_CASE_CONFLICTS 0x00001000 + +/** Do not ignore failure to set timestamps on extracted files. */ +#define WIMLIB_EXTRACT_FLAG_STRICT_TIMESTAMPS 0x00002000 + +/** Do not ignore failure to set short names on extracted files. */ +#define WIMLIB_EXTRACT_FLAG_STRICT_SHORT_NAMES 0x00004000 + +/** Do not ignore failure to extract symbolic links (and junction points, on + * Windows) due to permissions problems. By default, such failures are ignored + * since the default configuration of Windows only allows the Administrator to + * create symbolic links. */ +#define WIMLIB_EXTRACT_FLAG_STRICT_SYMLINKS 0x00008000 + + /****************************** * WIMLIB_MOUNT_FLAG_* ******************************/ @@ -755,12 +1082,24 @@ struct wimlib_capture_config { * WIMLIB_OPEN_FLAG_* ******************************/ -/** Verify the WIM contents against the WIM's integrity table, if present. */ +/** Verify the WIM contents against the WIM's integrity table, if present. This + * causes the raw data of the WIM file, divided into 10 MB chunks, to be + * checksummed and checked against the SHA1 message digests specified in the + * integrity table. WIMLIB_ERR_INTEGRITY is returned if there are any + * mismatches. */ #define WIMLIB_OPEN_FLAG_CHECK_INTEGRITY 0x00000001 -/** Do not issue an error if the WIM is part of a split WIM. */ +/** Do not issue an error if the WIM is part of a split WIM. */ #define WIMLIB_OPEN_FLAG_SPLIT_OK 0x00000002 +/** Check if the WIM is writable and return ::WIMLIB_ERR_WIM_IS_READONLY if it + * is not. A WIM is considered writable only if it is writable at the + * filesystem level, does not have the WIM_HDR_FLAG_READONLY flag set in its + * header, and is not part of a spanned set. It is not required to provide this + * flag to make changes to the WIM, but with this flag you get the error sooner + * rather than later. */ +#define WIMLIB_OPEN_FLAG_WRITE_ACCESS 0x00000004 + /****************************** * WIMLIB_UNMOUNT_FLAG_* ******************************/ @@ -782,44 +1121,92 @@ struct wimlib_capture_config { /** Do a "lazy" unmount (detach filesystem immediately, even if busy) */ #define WIMLIB_UNMOUNT_FLAG_LAZY 0x00000010 +/****************************** + * WIMLIB_UPDATE_FLAG_* + ******************************/ + +/** Send ::WIMLIB_PROGRESS_MSG_UPDATE_BEGIN_COMMAND and + * ::WIMLIB_PROGRESS_MSG_UPDATE_END_COMMAND messages. */ +#define WIMLIB_UPDATE_FLAG_SEND_PROGRESS 0x00000001 + /****************************** * WIMLIB_WRITE_FLAG_* ******************************/ -/** Include an integrity table in the new WIM file. */ +/** Include an integrity table in the WIM. + * + * For WIMs created with wimlib_open_wim(), the default behavior is to include + * an integrity table if and only if one was present before. For WIMs created + * with wimlib_create_new_wim(), the default behavior is to not include an + * integrity table. */ #define WIMLIB_WRITE_FLAG_CHECK_INTEGRITY 0x00000001 -/** Re-build the entire WIM file rather than appending data to it, if possible. - * (Applies to wimlib_overwrite(), not wimlib_write()). */ -#define WIMLIB_WRITE_FLAG_REBUILD 0x00000002 +/** Do not include an integrity table in the new WIM file. This is the default + * behavior, unless the WIM already included an integrity table. */ +#define WIMLIB_WRITE_FLAG_NO_CHECK_INTEGRITY 0x00000002 -/** Recompress all resources, even if they could otherwise be copied from a - * different WIM with the same compression type (in the case of - * wimlib_export_image() being called previously). */ -#define WIMLIB_WRITE_FLAG_RECOMPRESS 0x00000004 +/** Write the WIM as "pipable". After writing a WIM with this flag specified, + * images from it can be applied directly from a pipe using + * wimlib_extract_image_from_pipe(). See the documentation for the --pipable + * flag of `wimlib-imagex capture' for more information. Beware: WIMs written + * with this flag will not be compatible with Microsoft's software. + * + * For WIMs created with wimlib_open_wim(), the default behavior is to write the + * WIM as pipable if and only if it was pipable before. For WIMs created with + * wimlib_create_new_wim(), the default behavior is to write the WIM as + * non-pipable. */ +#define WIMLIB_WRITE_FLAG_PIPABLE 0x00000004 -/** Call fsync() when the WIM file is closed */ -#define WIMLIB_WRITE_FLAG_FSYNC 0x00000008 +/** Do not write the WIM as "pipable". This is the default behavior, unless the + * WIM was pipable already. */ +#define WIMLIB_WRITE_FLAG_NOT_PIPABLE 0x00000008 -/* 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. - * - * If you specifiy this flag to wimlib_overwrite(), only minimal changes to - * correctly remove the image from the WIM will be taken. In particular, all - * streams will be left alone, even if they are no longer referenced. This is - * probably not what you want, because almost no space will be spaced by - * deleting an image in this way. */ -#define WIMLIB_WRITE_FLAG_SOFT_DELETE 0x00000010 +/** Recompress all resources, even if they could otherwise be copied from a + * different WIM with the same compression type (in the case of + * wimlib_export_image() being called previously). This flag is also valid in + * the @p wim_write_flags of wimlib_join(), in which case all resources included + * in the joined WIM file will be recompressed. */ +#define WIMLIB_WRITE_FLAG_RECOMPRESS 0x00000010 + +/** Call fsync() just before the WIM file is closed. */ +#define WIMLIB_WRITE_FLAG_FSYNC 0x00000020 + +/** wimlib_overwrite() only: Re-build the entire WIM file rather than appending + * data to it if possible. */ +#define WIMLIB_WRITE_FLAG_REBUILD 0x00000040 + +/** wimlib_overwrite() only: 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. With this flag, + * only minimal changes to correctly remove the image from the WIM will be + * taken. In particular, all streams will be left alone, even if they are no + * longer referenced. This is probably not what you want, because almost no + * space will be saved by deleting an image in this way. */ +#define WIMLIB_WRITE_FLAG_SOFT_DELETE 0x00000080 + +/** wimlib_overwrite() only: Allow overwriting the WIM even if the readonly + * flag is set in the WIM header. This can be used in combination with + * wimlib_set_wim_info() with the ::WIMLIB_CHANGE_READONLY_FLAG flag to actually + * set the readonly flag on the on-disk WIM file. */ +#define WIMLIB_WRITE_FLAG_IGNORE_READONLY_FLAG 0x00000100 /****************************** * WIMLIB_INIT_FLAG_* ******************************/ /** Assume that strings are represented in UTF-8, even if this is not the - * locale's character encoding. */ + * locale's character encoding. Not used on Windows. */ #define WIMLIB_INIT_FLAG_ASSUME_UTF8 0x00000001 +/** Windows-only: do not attempt to acquire additional privileges (currently + * SeBackupPrivilege, SeRestorePrivilege, SeSecurityPrivilege, and + * SeTakeOwnershipPrivilege) when initializing the library. This is intended + * for the case where the calling program manages these privileges itself. + * Note: no error is issued if privileges cannot be acquired, although related + * errors may be reported later, depending on if the operations performed + * actually require additional privileges or not. */ +#define WIMLIB_INIT_FLAG_DONT_ACQUIRE_PRIVILEGES 0x00000002 + /** Specification of an update to perform on a WIM image. */ struct wimlib_update_command { @@ -901,7 +1288,6 @@ struct wimlib_extract_command { 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, @@ -911,23 +1297,22 @@ enum wimlib_error_code { 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, WIMLIB_ERR_INVALID_COMPRESSION_TYPE, - WIMLIB_ERR_INVALID_DENTRY, - WIMLIB_ERR_INVALID_HEADER_SIZE, + WIMLIB_ERR_INVALID_HEADER, WIMLIB_ERR_INVALID_IMAGE, WIMLIB_ERR_INVALID_INTEGRITY_TABLE, WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY, + WIMLIB_ERR_INVALID_METADATA_RESOURCE, WIMLIB_ERR_INVALID_MULTIBYTE_STRING, WIMLIB_ERR_INVALID_OVERLAY, WIMLIB_ERR_INVALID_PARAM, WIMLIB_ERR_INVALID_PART_NUMBER, + WIMLIB_ERR_INVALID_PIPABLE_WIM, 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, @@ -942,6 +1327,7 @@ enum wimlib_error_code { WIMLIB_ERR_NOTEMPTY, WIMLIB_ERR_NOT_A_REGULAR_FILE, WIMLIB_ERR_NOT_A_WIM_FILE, + WIMLIB_ERR_NOT_PIPABLE, WIMLIB_ERR_NO_FILENAME, WIMLIB_ERR_NTFS_3G, WIMLIB_ERR_OPEN, @@ -952,16 +1338,22 @@ enum wimlib_error_code { WIMLIB_ERR_RENAME, WIMLIB_ERR_REOPEN, WIMLIB_ERR_REPARSE_POINT_FIXUP_FAILED, + WIMLIB_ERR_RESOURCE_NOT_FOUND, WIMLIB_ERR_RESOURCE_ORDER, + WIMLIB_ERR_SET_ATTRIBUTES, + WIMLIB_ERR_SET_SECURITY, + WIMLIB_ERR_SET_TIMESTAMPS, WIMLIB_ERR_SPECIAL_FILE, WIMLIB_ERR_SPLIT_INVALID, WIMLIB_ERR_SPLIT_UNSUPPORTED, WIMLIB_ERR_STAT, WIMLIB_ERR_TIMEOUT, + WIMLIB_ERR_UNEXPECTED_END_OF_FILE, WIMLIB_ERR_UNICODE_STRING_NOT_REPRESENTABLE, WIMLIB_ERR_UNKNOWN_VERSION, WIMLIB_ERR_UNSUPPORTED, WIMLIB_ERR_VOLUME_LACKS_FEATURES, + WIMLIB_ERR_WIM_IS_READONLY, WIMLIB_ERR_WRITE, WIMLIB_ERR_XML, }; @@ -976,27 +1368,33 @@ enum wimlib_error_code { /** * 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. + * modifications, a root directory will be created automatically for it. After + * calling this function, you can use wimlib_update_image() to add files to the + * new WIM image. This gives you slightly more control over making the new + * image compared to calling wimlib_add_image() or + * wimlib_add_image_multisource() directly. * * @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. + * Name to give the new image. If @c NULL or empty, the new image is given + * no name. If nonempty, it must specify a name that does not already + * exist in @a wim. * @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. + * @retval ::WIMLIB_ERR_WIM_IS_READONLY + * The WIM file is considered read-only because of any of the reasons + * mentioned in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS + * flag. */ extern int wimlib_add_empty_image(WIMStruct *wim, @@ -1025,8 +1423,9 @@ wimlib_add_empty_image(WIMStruct *wim, * A path to a directory or unmounted NTFS volume that will be captured as * a WIM image. * @param name - * The name to give the image. It must be nonempty and must specify a name - * that does not yet exist in @a wim. + * Name to give the new image. If @c NULL or empty, the new image is given + * no name. If nonempty, it must specify a name that does not already + * exist in @a wim. * @param config * Capture configuration that specifies files, directories, or path globs * to exclude from being captured. If @c NULL, a dummy configuration where @@ -1130,9 +1529,6 @@ wimlib_create_new_wim(int ctype, WIMStruct **wim_ret); * * @retval ::WIMLIB_ERR_DECOMPRESSION * Could not decompress the metadata resource for @a image. - * @retval ::WIMLIB_ERR_INVALID_DENTRY - * A directory entry in the metadata resource for @a image in the WIM is - * invalid. * @retval ::WIMLIB_ERR_INVALID_IMAGE * @a image does not exist in the WIM and is not ::WIMLIB_ALL_IMAGES. * @retval ::WIMLIB_ERR_INVALID_RESOURCE_SIZE @@ -1143,9 +1539,10 @@ wimlib_create_new_wim(int ctype, WIMStruct **wim_ret); * Failed to allocate needed memory. * @retval ::WIMLIB_ERR_READ * Could not read the metadata resource for @a image from the WIM. - * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED - * @a wim is part of a split WIM. Deleting an image from a split WIM is - * unsupported. + * @retval ::WIMLIB_ERR_WIM_IS_READONLY + * The WIM file is considered read-only because of any of the reasons + * mentioned in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS + * flag. */ extern int wimlib_delete_image(WIMStruct *wim, int image); @@ -1222,9 +1619,6 @@ wimlib_delete_image(WIMStruct *wim, int image); * @retval ::WIMLIB_ERR_IMAGE_NAME_COLLISION * One or more of the names being given to an exported image was already in * use in the destination WIM. - * @retval ::WIMLIB_ERR_INVALID_DENTRY - * A directory entry in the metadata resource for @a src_image in @a - * src_wim is invalid. * @retval ::WIMLIB_ERR_INVALID_IMAGE * @a src_image does not exist in @a src_wim. * @retval ::WIMLIB_ERR_INVALID_PARAM @@ -1246,9 +1640,10 @@ wimlib_delete_image(WIMStruct *wim, int image); * complete split WIM because they do not include all the parts of the * original WIM, there are duplicate parts, or not all the parts have the * same GUID and compression type. - * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED - * @a dest_wim is part of a split WIM. Exporting an image to a split WIM - * is unsupported. + * @retval ::WIMLIB_ERR_WIM_IS_READONLY + * @a dest_wim is considered read-only because of any of the reasons + * mentioned in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS + * flag. */ extern int wimlib_export_image(WIMStruct *src_wim, int src_image, @@ -1405,9 +1800,6 @@ wimlib_extract_files(WIMStruct *wim, * @retval ::WIMLIB_ERR_DECOMPRESSION * Could not decompress a resource (file or metadata) for @a image in @a * wim. - * @retval ::WIMLIB_ERR_INVALID_DENTRY - * A directory entry in the metadata resource for @a image in @a wim is - * invalid. * @retval ::WIMLIB_ERR_INVALID_PARAM * @a target was @c NULL, or both ::WIMLIB_EXTRACT_FLAG_HARDLINK and * ::WIMLIB_EXTRACT_FLAG_SYMLINK were specified in @a extract_flags; or @@ -1442,6 +1834,19 @@ wimlib_extract_files(WIMStruct *wim, * @retval ::WIMLIB_ERR_READ * A unexpected end-of-file or read error occurred when trying to read data * from the WIM file associated with @a wim. + * @retval ::WIMLIB_ERR_RESOURCE_NOT_FOUND + * One of the dentries in the image referenced a stream not present in the + * WIM's lookup table (or in any of the lookup tables of the split WIM + * parts). + * @retval ::WIMLIB_ERR_SET_ATTRIBUTES + * Failed to set attributes on a file. + * @retval ::WIMLIB_ERR_SET_SECURITY + * Failed to set security descriptor on a file + * (only if ::WIMLIB_EXTRACT_FLAG_STRICT_ACLS) specified in @p + * extract_flags. + * @retval ::WIMLIB_ERR_SET_TIMESTAMPS + * Failed to set timestamps on a file (only if + * ::WIMLIB_EXTRACT_FLAG_STRICT_TIMESTAMPS) specified in @p extract_flags. * @retval ::WIMLIB_ERR_SPLIT_INVALID * The WIM is a split WIM, but the parts specified do not form a complete * split WIM because they do not include all the parts of the original WIM, @@ -1462,6 +1867,52 @@ wimlib_extract_image(WIMStruct *wim, int image, unsigned num_additional_swms, wimlib_progress_func_t progress_func); +/** + * Since wimlib v1.5.0: Extract one or more images from a pipe on which a + * pipable WIM is being sent. + * + * See the documentation for ::WIMLIB_WRITE_FLAG_PIPABLE for more information + * about pipable WIMs. + * + * This function operates in a special way to read the WIM fully sequentially. + * As a result, there is no ::WIMStruct is made visible to library users, and + * you cannot call wimlib_open_wim() on the pipe. (You can, however, use + * wimlib_open_wim() to transparently open a pipable WIM if it's available as a + * seekable file, not a pipe.) + * + * @param pipe_fd + * File descriptor, which may be a pipe, opened for reading and positioned + * at the start of the pipable WIM. + * @param image_num_or_name + * String that specifies the 1-based index or name of the image to extract. + * It is translated to an image index using the same rules that + * wimlib_resolve_image() uses. However, unlike wimlib_extract_image(), + * only a single image (not all images) can be specified. Alternatively, + * specify @p NULL here to use the first image in the WIM if it contains + * exactly one image but otherwise return @p WIMLIB_ERR_INVALID_IMAGE. + * @param target + * Same as the corresponding parameter to wimlib_extract_image(). + * @param extract_flags + * Same as the corresponding parameter to wimlib_extract_image(), except + * for the following exceptions: ::WIMLIB_EXTRACT_FLAG_SEQUENTIAL is + * always implied, since data is always read from @p pipe_fd sequentially + * in this mode; also, ::WIMLIB_EXTRACT_FLAG_TO_STDOUT is invalid and will + * result in ::WIMLIB_ERR_INVALID_PARAM being returned. + * @param progress_func + * Same as the corresponding parameter to wimlib_extract_image(). + * + * @return 0 on success; nonzero on error. The possible error codes include + * those returned by wimlib_extract_image() as well as the following: + * + * @retval ::WIMLIB_ERR_NOT_PIPABLE + * The WIM being piped in a @p pipe_fd is a normal WIM, not a pipable WIM. + */ +extern int +wimlib_extract_image_from_pipe(int pipe_fd, + const wimlib_tchar *image_num_or_name, + const wimlib_tchar *target, int extract_flags, + wimlib_progress_func_t progress_func); + /** * Extracts the XML data of a WIM file to a file stream. Every WIM file * includes a string of XML that describes the images contained in the WIM. @@ -1498,30 +1949,16 @@ extern void wimlib_free(WIMStruct *wim); /** - * Returns the index of the bootable image of the WIM. - * - * @param wim - * Pointer to the ::WIMStruct for a WIM file. - * - * @return - * 0 if no image is marked as bootable, or the number of the image marked - * as bootable (numbered starting at 1). + * Deprecated in favor of wimlib_get_wim_info(). */ extern int -wimlib_get_boot_idx(const WIMStruct *wim); +wimlib_get_boot_idx(const WIMStruct *wim) _wimlib_deprecated; /** - * Returns the compression type used in the WIM. - * - * @param wim - * Pointer to the ::WIMStruct for a WIM file - * - * @return - * ::WIMLIB_COMPRESSION_TYPE_NONE, ::WIMLIB_COMPRESSION_TYPE_LZX, or - * ::WIMLIB_COMPRESSION_TYPE_XPRESS. + * Deprecated in favor of wimlib_get_wim_info(). */ extern int -wimlib_get_compression_type(const WIMStruct *wim); +wimlib_get_compression_type(const WIMStruct *wim) _wimlib_deprecated; /** * Converts a ::wimlib_compression_type value into a string. @@ -1593,44 +2030,41 @@ wimlib_get_image_name(const WIMStruct *wim, int image); /** - * Returns the number of images contained in a WIM. - * - * @param wim - * Pointer to the ::WIMStruct for a WIM file. It may be either a - * standalone WIM or a split WIM part. - * - * @return - * The number of images contained in the WIM file. + * Deprecated in favor of wimlib_get_wim_info(). */ extern int -wimlib_get_num_images(const WIMStruct *wim); +wimlib_get_num_images(const WIMStruct *wim) _wimlib_deprecated; /** - * Returns the part number of a WIM in a split WIM and the total number of parts - * of the split WIM. + * Deprecated in favor of wimlib_get_wim_info(). + */ +extern int +wimlib_get_part_number(const WIMStruct *wim, int *total_parts_ret) _wimlib_deprecated; + +/** + * Get basic information about a WIM file. * * @param wim - * Pointer to the ::WIMStruct for a WIM file. - * @param total_parts_ret - * If non-@c NULL, the total number of parts in the split WIM (1 for - * non-split WIMs) is written to this location. - * + * Pointer to the ::WIMStruct for a WIM file. It may be for either a + * standalone WIM or part of a split WIM. + * @param info + * A ::wimlib_wim_info structure that will be filled in with information + * about the WIM file. * @return - * The part number of the WIM (1 for non-split WIMs) + * 0 */ extern int -wimlib_get_part_number(const WIMStruct *wim, int *total_parts_ret); +wimlib_get_wim_info(WIMStruct *wim, struct wimlib_wim_info *info); /** * Initialization function for wimlib. Call before using any other wimlib - * function. + * function except wimlib_set_print_errors(). (However, currently this is not + * strictly necessary and it will be called automatically if not done manually, + * but you should not rely on this behavior.) * * @param init_flags - * On UNIX, specify ::WIMLIB_INIT_FLAG_ASSUME_UTF8 if wimlib should assume - * that all input data, including filenames, are in UTF-8 rather than the - * locale-dependent character encoding which may or may not be UTF-8, and - * that UTF-8 data can be directly printed to the console. On Windows, use - * 0 for this parameter. + * Bitwise OR of ::WIMLIB_INIT_FLAG_ASSUME_UTF8 and/or + * ::WIMLIB_INIT_FLAG_DONT_ACQUIRE_PRIVILEGES. * * @return 0; other error codes may be returned in future releases. */ @@ -1640,24 +2074,16 @@ 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. + * resources allocated by the library. */ extern void wimlib_global_cleanup(void); /** - * Returns true if the WIM has an integrity table. - * - * @param wim - * Pointer to the ::WIMStruct for a WIM file. - * @return - * @c true if the WIM has an integrity table; @c false otherwise. If @a - * wim is a ::WIMStruct created with wimlib_create_new_wim() rather than - * 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. + * Deprecated in favor of wimlib_get_wim_info(). */ extern bool -wimlib_has_integrity_table(const WIMStruct *wim); +wimlib_has_integrity_table(const WIMStruct *wim) _wimlib_deprecated; /** * Determines if an image name is already used by some image in the WIM. @@ -1675,6 +2101,76 @@ wimlib_has_integrity_table(const WIMStruct *wim); extern bool wimlib_image_name_in_use(const WIMStruct *wim, const wimlib_tchar *name); +/** + * Iterate through a file or directory tree in the WIM image. By specifying + * appropriate flags and a callback function, you can get the attributes of a + * file in the WIM, get a directory listing, or even get a listing of the entire + * WIM 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 that contains the files or + * directories to iterate over. + * + * @param path + * Path in the WIM image at which to do the iteration. + * + * @param flags + * Bitwise OR of ::WIMLIB_ITERATE_DIR_TREE_FLAG_RECURSIVE and/or + * ::WIMLIB_ITERATE_DIR_TREE_FLAG_CHILDREN. + * + * @param cb + * A callback function that will receive each directory entry. + * + * @param user_ctx + * An extra parameter that will always be passed to the callback function + * @a cb. + * + * @return Normally, returns 0 if all calls to @a cb returned 0; otherwise the + * first nonzero value that was returned from @a cb. However, additional error + * codes may be returned, including the following: + * + * @retval ::WIMLIB_ERR_PATH_DOES_NOT_EXIST + * @a path did not exist in the WIM image. + * @retval ::WIMLIB_ERR_NOMEM + * Failed to allocate memory needed to create a ::wimlib_dir_entry. + */ +extern int +wimlib_iterate_dir_tree(WIMStruct *wim, int image, const wimlib_tchar *path, + int flags, + wimlib_iterate_dir_tree_callback_t cb, void *user_ctx); + +/** + * Iterate through the lookup table of a WIM file. This can be used to directly + * get a listing of the unique resources contained in a WIM file. Both file + * resources and metadata resources are included. + * + * @param wim + * Pointer to the ::WIMStruct of a standalone WIM file or a split WIM part. + * Note: metadata resources will only be included if the WIM is standalone + * or the first part of the split WIM. + * + * @param flags + * Reserved; set to 0. + * + * @param cb + * A callback function that will receive each resource. + * + * @param user_ctx + * An extra parameter that will always be passed to the callback function + * @a cb. + * + * @return 0 if all calls to @a cb returned 0; otherwise the first nonzero value + * that was returned from @a cb. + */ +extern int +wimlib_iterate_lookup_table(WIMStruct *wim, int flags, + wimlib_iterate_lookup_table_callback_t cb, + void *user_ctx); + /** * Joins a split WIM into a stand-alone one-part WIM. * @@ -1698,7 +2194,7 @@ wimlib_image_name_in_use(const WIMStruct *wim, const wimlib_tchar *name); * * @return 0 on success; nonzero on error. This function may return any value * returned by wimlib_open_wim() and wimlib_write() except - * ::WIMLIB_ERR_SPLIT_UNSUPPORTED, as well as the following error code: + * ::WIMLIB_ERR_WIM_IS_READONLY, as well as the following error code: * * @retval ::WIMLIB_ERR_SPLIT_INVALID * The split WIMs do not form a valid WIM because they do not include all @@ -1838,9 +2334,6 @@ wimlib_lzx_decompress(const void *compressed_data, unsigned compressed_len, * Could not decompress the metadata resource for @a image in @a wim. * @retval ::WIMLIB_ERR_FUSE * A non-zero status was returned by @c fuse_main(). - * @retval ::WIMLIB_ERR_INVALID_DENTRY - * A directory entry in the metadata resource for @a image in @a wim is - * invalid. * @retval ::WIMLIB_ERR_INVALID_IMAGE * @a image does not specify an existing, single image in @a wim. * @retval ::WIMLIB_ERR_INVALID_PARAM @@ -1861,14 +2354,19 @@ wimlib_lzx_decompress(const void *compressed_data, unsigned compressed_len, * @retval ::WIMLIB_ERR_READ * An unexpected end-of-file or read error occurred when trying to read * data from the WIM file associated with @a wim. + * @retval ::WIMLIB_ERR_RESOURCE_NOT_FOUND + * One of the dentries in the image referenced a stream not present in the + * WIM's lookup table (or in any of the lookup tables of the split WIM + * parts). * @retval ::WIMLIB_ERR_SPLIT_INVALID * The WIM is a split WIM, but the parts specified do not form a complete * split WIM because they do not include all the parts of the original WIM, * there are duplicate parts, or not all the parts have the same GUID and * compression type. - * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED - * The WIM is a split WIM and a read-write mount was requested. We only - * support mounting a split WIM read-only. + * @retval ::WIMLIB_ERR_WIM_IS_READONLY + * ::WIMLIB_MOUNT_FLAG_READWRITE was specified in @a mount_flags, but @a + * wim is considered read-only because of any of the reasons mentioned in + * the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS flag. * @retval ::WIMLIB_ERR_UNSUPPORTED * Mounting is not supported, either because the platform is Windows, or * because the platform is UNIX and wimlib was compiled with @c @@ -1890,18 +2388,7 @@ wimlib_mount_image(WIMStruct *wim, * The path to the WIM file to open. * @param open_flags * Bitwise OR of flags ::WIMLIB_OPEN_FLAG_CHECK_INTEGRITY and/or - * ::WIMLIB_OPEN_FLAG_SPLIT_OK. - *

- * If ::WIMLIB_OPEN_FLAG_CHECK_INTEGRITY is given, the integrity table of - * the WIM, if it exists, is checked, and this function will fail with an - * ::WIMLIB_ERR_INTEGRITY status if any of the computed SHA1 message - * digests of the WIM do not exactly match the corresponding message - * digests given in the integrity table. - *

- * If ::WIMLIB_OPEN_FLAG_SPLIT_OK is given, no error will be issued if the - * WIM is part of a split WIM; otherwise ::WIMLIB_ERR_SPLIT_UNSUPPORTED is - * returned. (This flag may be removed in the future, in which case no - * error will be issued when opening a split WIM.) + * ::WIMLIB_OPEN_FLAG_SPLIT_OK and/or ::WIMLIB_OPEN_FLAG_WRITE_ACCESS. * * @param progress_func * If non-NULL, a function that will be called periodically with the @@ -1933,7 +2420,7 @@ wimlib_mount_image(WIMStruct *wim, * @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE * The header of @a wim_file says that resources in the WIM are compressed, * but the header flag indicating LZX or XPRESS compression is not set. - * @retval ::WIMLIB_ERR_INVALID_HEADER_SIZE + * @retval ::WIMLIB_ERR_INVALID_HEADER * The length field of the WIM header is not 208. * @retval ::WIMLIB_ERR_INVALID_INTEGRITY_TABLE * ::WIMLIB_OPEN_FLAG_CHECK_INTEGRITY was specified in @a open_flags and @a @@ -1943,6 +2430,8 @@ wimlib_mount_image(WIMStruct *wim, * 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. + * @retval ::WIMLIB_ERR_INVALID_PARAM + * @p wim_ret was @c NULL. * @retval ::WIMLIB_ERR_NOMEM * Failed to allocated needed memory. * @retval ::WIMLIB_ERR_NOT_A_WIM_FILE @@ -1958,6 +2447,10 @@ wimlib_mount_image(WIMStruct *wim, * @retval ::WIMLIB_ERR_UNKNOWN_VERSION * A number other than 0x10d00 is written in the version field of the WIM * header of @a wim_file. (Probably 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 + * documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS flag. * @retval ::WIMLIB_ERR_XML * The XML data for @a wim_file is invalid. */ @@ -2026,7 +2519,7 @@ wimlib_open_wim(const wimlib_tchar *wim_file, * @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 WIM was going to be modifien in-place (with no temporary file), but + * The WIM was going to be modified 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. @@ -2036,6 +2529,10 @@ wimlib_open_wim(const wimlib_tchar *wim_file, * @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_WIM_IS_READONLY + * The WIM file is considered read-only because of any of the reasons + * mentioned in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS + * flag. */ extern int wimlib_overwrite(WIMStruct *wim, int write_flags, unsigned num_threads, @@ -2059,119 +2556,39 @@ 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 - * WIM file. - * - * @param wim - * Pointer to the ::WIMStruct for a WIM file. - * @param image - * Which image to print files for. Can be the number of an image, or - * ::WIMLIB_ALL_IMAGES to print the files contained in all images. - * - * @return 0 on success; nonzero on error. - * @retval ::WIMLIB_ERR_DECOMPRESSION - * The metadata resource for one of the specified images could not be - * decompressed. - * @retval ::WIMLIB_ERR_INVALID_DENTRY - * A directory entry in the metadata resource for one of the specified - * images is invaled. - * @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_RESOURCE_SIZE - * The metadata resource for one of the specified images is invalid. - * @retval ::WIMLIB_ERR_INVALID_SECURITY_DATA - * The security data for one of the specified images is invalid. - * @retval ::WIMLIB_ERR_NOMEM - * Failed to allocate needed memory. - * @retval ::WIMLIB_ERR_READ - * An unexpected read error or end-of-file occurred when reading the - * metadata resource for one of the specified images. - * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED - * @a wim was not a standalone WIM and was not the first part of a split - * WIM. + * Deprecated in favor of wimlib_iterate_dir_tree(), which provides the + * information in a way that can be accessed programatically. */ extern int -wimlib_print_files(WIMStruct *wim, int image); +wimlib_print_files(WIMStruct *wim, int image) _wimlib_deprecated; /** - * Prints detailed information from the header of a WIM file. - * - * @param wim - * Pointer to the ::WIMStruct for a WIM file. It may be either a - * standalone WIM or part of a split WIM. - * - * @return This function has no return value. - * + * Deprecated in favor of wimlib_get_wim_info(), which provides the information + * in a way that can be accessed programatically. */ extern void -wimlib_print_header(const WIMStruct *wim); +wimlib_print_header(const WIMStruct *wim) _wimlib_deprecated; /** - * Prints the lookup table of a WIM file. The lookup table maps SHA1 message - * digests, as found in the directory entry tree in the WIM file, to file - * resources in the WIM file. This table includes one entry for each unique - * file in the WIM, so it can be quite long. There is only one lookup table per - * WIM file, but each split WIM part has its own lookup table. - * - * @param wim - * Pointer to the ::WIMStruct for a WIM file. - * - * @return This function has no return value. + * Deprecated in favor of wimlib_iterate_lookup_table(), which provides the + * information in a way that can be accessed programatically. */ extern void -wimlib_print_lookup_table(WIMStruct *wim); +wimlib_print_lookup_table(WIMStruct *wim) _wimlib_deprecated; /** - * Prints the metadata of the specified image in a WIM file. The metadata - * consists of the security data as well as the directory entry tree. Each - * image has its own metadata. - * - * @param wim - * Pointer to the ::WIMStruct for a WIM file. - * @param image - * Which image to print the metadata for. Can be the number of an image, - * or ::WIMLIB_ALL_IMAGES to print the metadata for all images in the WIM. - * - * @return 0 on success; nonzero on error. - * @retval ::WIMLIB_ERR_DECOMPRESSION - * The metadata resource for one of the specified images could not be - * decompressed. - * @retval ::WIMLIB_ERR_INVALID_DENTRY - * A directory entry in the metadata resource for one of the specified - * images is invaled. - * @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_RESOURCE_SIZE - * The metadata resource for one of the specified images is invalid. - * @retval ::WIMLIB_ERR_INVALID_SECURITY_DATA - * The security data for one of the specified images is invalid. - * @retval ::WIMLIB_ERR_NOMEM - * Failed to allocate needed memory. - * @retval ::WIMLIB_ERR_READ - * An unexpected read error or end-of-file occurred when reading the - * metadata resource for one of the specified images. - * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED - * @a wim was not a standalone WIM and was not the first part of a split - * WIM. + * 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_print_metadata(WIMStruct *wim, int image) _wimlib_deprecated; /** - * Prints some basic information about a WIM file. All information printed by - * this function is also printed by wimlib_print_header(), but - * wimlib_print_wim_information() prints some of this information more concisely - * and in a more readable form. - * - * @param wim - * Pointer to the ::WIMStruct for a WIM file. - * - * @return This function has no return value. + * Deprecated in favor of wimlib_get_wim_info(), which provides the information + * in a way that can be accessed programatically. */ extern void -wimlib_print_wim_information(const WIMStruct *wim); +wimlib_print_wim_information(const WIMStruct *wim) _wimlib_deprecated; /** * Translates a string specifying the name or number of an image in the WIM into @@ -2204,23 +2621,10 @@ wimlib_resolve_image(WIMStruct *wim, const wimlib_tchar *image_name_or_num); /** - * Sets which image in the WIM is marked as bootable. - * - * @param wim - * Pointer to the ::WIMStruct for a WIM file. - * @param boot_idx - * 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_IMAGE - * @a boot_idx does not specify an existing image in @a wim, and it was not - * 0. - * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED - * @a wim is part of a split WIM. We do not support changing the boot - * index of a split WIM. + * Deprecated in favor of wimlib_set_wim_info(). */ extern int -wimlib_set_boot_idx(WIMStruct *wim, int boot_idx); +wimlib_set_boot_idx(WIMStruct *wim, int boot_idx) _wimlib_deprecated; /** * Changes the description of an image in the WIM. @@ -2241,11 +2645,44 @@ wimlib_set_boot_idx(WIMStruct *wim, int boot_idx); * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate the memory needed to duplicate the @a description * string. + * @retval ::WIMLIB_ERR_WIM_IS_READONLY + * @a wim is considered read-only because of any of the reasons mentioned + * in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS flag. */ extern int wimlib_set_image_descripton(WIMStruct *wim, int image, const wimlib_tchar *description); +/** + * Set basic information about a WIM. + * + * @param wim + * A WIMStruct for a standalone WIM file. + * @param info + * A struct ::wimlib_wim_info that contains the information to set. Only + * the information explicitly specified in the @a which flags need be + * valid. + * @param which + * Flags that specify which information to set. This is a bitwise OR of + * ::WIMLIB_CHANGE_READONLY_FLAG, ::WIMLIB_CHANGE_GUID, + * ::WIMLIB_CHANGE_BOOT_INDEX, and/or ::WIMLIB_CHANGE_RPFIX_FLAG. + * + * @return 0 on success; nonzero on failure. + * @retval ::WIMLIB_ERR_WIM_IS_READONLY + * The WIM file is considered read-only because of any of the reasons + * mentioned in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS + * flag. However, as a special case, if you are using + * ::WIMLIB_CHANGE_READONLY_FLAG to unset the readonly flag, then this + * function will not fail due to the readonly flag being previously set. + * @retval ::WIMLIB_ERR_IMAGE_COUNT + * ::WIMLIB_CHANGE_BOOT_INDEX was specified, but + * ::wimlib_wim_info.boot_index did not specify 0 or a valid 1-based image + * index in the WIM. + */ +extern int +wimlib_set_wim_info(WIMStruct *wim, const struct wimlib_wim_info *info, + int which); + /** * Changes what is written in the \ element in the WIM XML data * (something like "Core" or "Ultimate") @@ -2265,9 +2702,12 @@ wimlib_set_image_descripton(WIMStruct *wim, int 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 flags string. + * @retval ::WIMLIB_ERR_WIM_IS_READONLY + * @a wim is considered read-only because of any of the reasons mentioned + * in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS flag. */ -extern int wimlib_set_image_flags(WIMStruct *wim, int image, - const wimlib_tchar *flags); +extern int +wimlib_set_image_flags(WIMStruct *wim, int image, const wimlib_tchar *flags); /** * Changes the name of an image in the WIM. @@ -2279,17 +2719,20 @@ extern int wimlib_set_image_flags(WIMStruct *wim, int image, * @param image * The number of the image for which to change the name. * @param name - * The new name to give the image. It must be a nonempty string. + * New name to give the new image. If @c NULL or empty, the new image is + * given no name. If nonempty, it must specify a name that does not + * already exist in @a wim. * * @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. * @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. + * @retval ::WIMLIB_ERR_WIM_IS_READONLY + * @a wim is considered read-only because of any of the reasons mentioned + * in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS flag. */ extern int wimlib_set_image_name(WIMStruct *wim, int image, const wimlib_tchar *name); @@ -2337,6 +2780,8 @@ wimlib_set_memory_allocator(void *(*malloc_func)(size_t), * * By default, error messages are not printed. * + * This can be called before wimlib_global_init(). + * * @param show_messages * @c true if error messages are to be printed; @c false if error messages * are not to be printed. @@ -2387,7 +2832,7 @@ wimlib_set_print_errors(bool show_messages); extern int wimlib_split(WIMStruct *wim, const wimlib_tchar *swm_name, - size_t part_size, + uint64_t part_size, int write_flags, wimlib_progress_func_t progress_func); @@ -2471,7 +2916,7 @@ wimlib_unmount_image(const wimlib_tchar *dir, * @param num_cmds * Number of commands in @a cmds. * @param update_flags - * Reserved; must be 0. + * ::WIMLIB_UPDATE_FLAG_SEND_PROGRESS or 0. * @param progress_func * If non-NULL, a function that will be called periodically with the * progress of the current operation. @@ -2485,8 +2930,6 @@ wimlib_unmount_image(const wimlib_tchar *dir, * @retval ::WIMLIB_ERR_INVALID_CAPTURE_CONFIG * The capture configuration structure specified for an add command was * invalid. - * @retval ::WIMLIB_ERR_INVALID_DENTRY - * A directory entry for @a image in @a wim is invalid. * @retval ::WIMLIB_ERR_INVALID_IMAGE * @a image did not specify a single, existing image in @a wim. * @retval ::WIMLIB_ERR_INVALID_OVERLAY @@ -2558,6 +3001,10 @@ wimlib_unmount_image(const wimlib_tchar *dir, * or, the platform is Windows and either the ::WIMLIB_ADD_FLAG_UNIX_DATA * or the ::WIMLIB_ADD_FLAG_DEREFERENCE flags were specified in the @a * add_flags for an update command. + * @retval ::WIMLIB_ERR_WIM_IS_READONLY + * The WIM file is considered read-only because of any of the reasons + * mentioned in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS + * flag. */ extern int wimlib_update_image(WIMStruct *wim, @@ -2580,12 +3027,10 @@ wimlib_update_image(WIMStruct *wim, * @param path * The path to the file to write the WIM to. * @param image - * The image inside the WIM to write. Use ::WIMLIB_ALL_IMAGES to include all - * images. + * The 1-based index of the image inside the WIM to write. Use + * ::WIMLIB_ALL_IMAGES to include all images. * @param write_flags - * Bitwise OR of the flags ::WIMLIB_WRITE_FLAG_CHECK_INTEGRITY, - * ::WIMLIB_WRITE_FLAG_RECOMPRESS, ::WIMLIB_WRITE_FLAG_FSYNC, and/or - * ::WIMLIB_WRITE_FLAG_SOFT_DELETE. + * Bitwise OR of any of the flags prefixed with @c WIMLIB_WRITE_FLAG. * @param num_threads * Number of threads to use for compressing data. If 0, the number of * threads is taken to be the number of online processors. Note: if no @@ -2596,14 +3041,14 @@ wimlib_update_image(WIMStruct *wim, * write_flags). * @param progress_func * If non-NULL, a function that will be called periodically with the - * progress of the current operation. + * progress of the current operation. The possible messages are + * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_BEGIN, + * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_END, and + * ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS. * * @return 0 on success; nonzero on error. * @retval ::WIMLIB_ERR_DECOMPRESSION * Failed to decompress a metadata or file resource in @a wim. - * @retval ::WIMLIB_ERR_INVALID_DENTRY - * A directory entry in the metadata resource for @a image in @a wim is - * invalid. * @retval ::WIMLIB_ERR_INVALID_IMAGE * @a image does not specify a single existing image in @a wim, and is not * ::WIMLIB_ALL_IMAGES. @@ -2612,7 +3057,7 @@ wimlib_update_image(WIMStruct *wim, * wimlib_add_image() was concurrently modified, so it failed the SHA1 * message digest check. * @retval ::WIMLIB_ERR_INVALID_PARAM - * @a path was @c NULL. + * @p 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 @@ -2620,20 +3065,18 @@ wimlib_update_image(WIMStruct *wim, * @retval ::WIMLIB_ERR_NOMEM * Failed to allocate needed memory. * @retval ::WIMLIB_ERR_OPEN - * Failed to open @a path for writing, or some file resources in @a - * wim refer to files in the outside filesystem, and one of these files - * could not be opened for reading. + * Failed to open @a path for writing, or some file resources in @a wim + * refer to files in the outside filesystem, and one of these files could + * not be opened for reading. * @retval ::WIMLIB_ERR_READ * An error occurred when trying to read data from the WIM file associated * with @a wim, or some file resources in @a wim refer to files in the * outside filesystem, and a read error occurred when reading one of these * files. * @retval ::WIMLIB_ERR_SPLIT_UNSUPPORTED - * @a wim is part of a split WIM. You may not call this function on a - * split WIM. + * @a wim is part of a split WIM, not a standalone WIM. * @retval ::WIMLIB_ERR_WRITE - * An error occurred when trying to write data to the new WIM file at @a - * path. + * An error occurred when trying to write data to the new WIM file. */ extern int wimlib_write(WIMStruct *wim, @@ -2643,6 +3086,31 @@ wimlib_write(WIMStruct *wim, unsigned num_threads, wimlib_progress_func_t progress_func); +/** + * Since wimlib v1.5.0: Same as wimlib_write(), but write the WIM directly to a + * file descriptor, which need not be seekable if the write is done in a special + * pipable WIM format by providing ::WIMLIB_WRITE_FLAG_PIPABLE in @p + * write_flags. This can, for example, allow capturing a WIM image and + * streaming it over the network. See the documentation for + * ::WIMLIB_WRITE_FLAG_PIPABLE for more information about pipable WIMs. + * + * The file descriptor @p fd will not be closed when the write is complete; the + * calling code is responsible for this. + * + * Return values are mostly the same as wimlib_write(), but also: + * + * @retval ::WIMLIB_ERR_INVALID_PARAM + * @p fd was not seekable, but ::WIMLIB_WRITE_FLAG_PIPABLE was not + * specified in @p write_flags. + */ +extern int +wimlib_write_to_fd(WIMStruct *wim, + int fd, + 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.