Progress callbacks have been added to wimlib's wimlib_update_image()
function.
- Added wimlib_get_wim_info() and wimlib_set_wim_info() functions.
+ Added wimlib_get_wim_info(), wimlib_set_wim_info(),
+ wimlib_iterate_dir_tree(), and wimlib_iterate_lookup_table() functions
+ to the library.
NTFS-3g capture now only warns about two conditions previously treated
as errors.
uint32_t reserved[9];
};
-/** Iterate recursively on children rather than just on the specified path. */
-#define WIMLIB_ITERATE_DIR_TREE_FLAG_RECURSIVE 0x00000001
+/** Information about a unique resource in the WIM file.
+ */
+struct wimlib_resource_entry {
+ /** Uncompressed size of the resource in bytes. */
+ uint64_t uncompressed_size;
-/** 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
+ /** 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;
-
- /** Size of the stream (uncompressed) in bytes. */
- uint64_t stream_size;
-
- uint64_t reserved[10];
+ /** Location, size, etc. of the stream within the WIM file. */
+ struct wimlib_resource_entry resource;
+ uint64_t reserved[4];
};
-/** Roughly, the information about "file" in the WIM--- 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_wim_dentry {
+/** 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;
};
/**
- * Type of a callback function to wimlib_iterate_dir_tree().
+ * 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_wim_dentry *dentry,
+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_*
* An extra parameter that will always be passed to the callback function
* @a cb.
*
- * @return 0 on success; nonzero on failure.
+ * @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.
*
extern void
wimlib_print_available_images(const WIMStruct *wim, int image);
-/** TODO: wimlib-imagex uses this for the 'dir' command, but a better API is
- * needed for this. */
+/**
+ * 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_deprecated;
-/** TODO: wimlib-imagex uses this for the 'info --header' command, but a better
- * API is needed for this. */
+/**
+ * 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_deprecated;
-/** TODO: wimlib-imagex uses this for the 'info --lookup-table' command, but a
- * better API is needed for this. */
+/**
+ * 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_deprecated;
-/** TODO: wimlib-imagex uses this for the 'info --metadata' command, but a
- * better API is needed for this. */
+/**
+ * Deprecated in favor of wimlib_iterate_dir_tree(), which provides the
+ * information in a way that can be accessed programatically.
+ */
extern int
wimlib_print_metadata(WIMStruct *wim, int image) _wimlib_deprecated;
extern void
free_lookup_table_entry(struct wim_lookup_table_entry *lte);
+extern void
+lte_to_wimlib_resource_entry(const struct wim_lookup_table_entry *lte,
+ struct wimlib_resource_entry *wentry);
+
extern int
for_lookup_table_entry(struct wim_lookup_table *table,
int (*visitor)(struct wim_lookup_table_entry *, void *),
}
static int
-print_full_path(const struct wimlib_wim_dentry *wdentry, void *_ignore)
+print_full_path(const struct wimlib_dir_entry *wdentry, void *_ignore)
{
int ret = tprintf(T("%"TS"\n"), wdentry->full_path);
return (ret >= 0) ? 0 : -1;
}
static void
-print_wim_information(const tchar *wimfile, WIMStruct *wim)
+print_wim_information(const tchar *wimfile, const struct wimlib_wim_info *info)
{
- struct wimlib_wim_info info;
-
- wimlib_get_wim_info((WIMStruct*)wim, &info);
-
tputs(T("WIM Information:"));
tputs(T("----------------"));
tprintf(T("Path: %"TS"\n"), wimfile);
- tfputs(T("GUID: 0x"), stdout);
- print_byte_field(info.guid, WIMLIB_GUID_LEN);
+ tprintf(T("GUID: 0x"));
+ print_byte_field(info->guid, sizeof(info->guid));
tputchar(T('\n'));
- tprintf(T("Image Count: %d\n"), info.image_count);
+ tprintf(T("Image Count: %d\n"), info->image_count);
tprintf(T("Compression: %"TS"\n"),
- wimlib_get_compression_type_string(info.compression_type));
- tprintf(T("Part Number: %d/%d\n"), info.part_number, info.total_parts);
- tprintf(T("Boot Index: %d\n"), info.boot_index);
- tprintf(T("Size: %"PRIu64" bytes\n"), info.total_bytes);
+ wimlib_get_compression_type_string(info->compression_type));
+ tprintf(T("Part Number: %d/%d\n"), info->part_number, info->total_parts);
+ tprintf(T("Boot Index: %d\n"), info->boot_index);
+ tprintf(T("Size: %"PRIu64" bytes\n"), info->total_bytes);
tprintf(T("Integrity Info: %"TS"\n"),
- info.has_integrity_table ? T("yes") : T("no"));
+ info->has_integrity_table ? T("yes") : T("no"));
tprintf(T("Relative path junction: %"TS"\n"),
- info.has_rpfix ? T("yes") : T("no"));
+ info->has_rpfix ? T("yes") : T("no"));
+ tputchar(T('\n'));
+}
+
+static int
+print_resource(const struct wimlib_resource_entry *resource,
+ void *_ignore)
+{
+
+ tprintf(T("Uncompressed size = %"PRIu64" bytes\n"),
+ resource->uncompressed_size);
+
+ tprintf(T("Compressed size = %"PRIu64" bytes\n"),
+ resource->compressed_size);
+
+ tprintf(T("Offset = %"PRIu64" bytes\n"),
+ resource->offset);
+
+
+ tprintf(T("Part Number = %u\n"), resource->part_number);
+ tprintf(T("Reference Count = %u\n"), resource->reference_count);
+
+ tprintf(T("Hash = 0x"));
+ print_byte_field(resource->sha1_hash, sizeof(resource->sha1_hash));
+ tputchar(T('\n'));
+
+ tprintf(T("Flags = "));
+ if (resource->is_compressed)
+ tprintf(T("WIM_RESHDR_FLAG_COMPRESSED "));
+ if (resource->is_metadata)
+ tprintf(T("WIM_RESHDR_FLAG_METADATA "));
+ if (resource->is_free)
+ tprintf(T("WIM_RESHDR_FLAG_FREE "));
+ if (resource->is_spanned)
+ tprintf(T("WIM_RESHDR_FLAG_SPANNED "));
+ tputchar(T('\n'));
tputchar(T('\n'));
+ return 0;
+}
+
+static void
+print_lookup_table(WIMStruct *wim)
+{
+ wimlib_iterate_lookup_table(wim, 0, print_resource, NULL);
}
/* Prints information about a WIM file; also can mark an image as bootable,
int image;
int ret;
int open_flags = WIMLIB_OPEN_FLAG_SPLIT_OK;
- int part_number;
- int total_parts;
- int num_images;
+ struct wimlib_wim_info info;
for_opt(c, info_options) {
switch (c) {
if (ret != 0)
return ret;
- part_number = wimlib_get_part_number(w, &total_parts);
+ wimlib_get_wim_info(w, &info);
image = wimlib_resolve_image(w, image_num_or_name);
if (image == WIMLIB_NO_IMAGE && tstrcmp(image_num_or_name, T("0"))) {
goto out;
}
- num_images = wimlib_get_num_images(w);
-
- if (num_images == 0) {
+ if (info.image_count == 0) {
if (boot) {
imagex_error(T("--boot is meaningless on a WIM with no "
"images"));
}
}
- if (image == WIMLIB_ALL_IMAGES && num_images > 1) {
+ if (image == WIMLIB_ALL_IMAGES && info.image_count > 1) {
if (boot) {
imagex_error(T("Cannot specify the --boot flag "
"without specifying a specific "
}
if (image == WIMLIB_ALL_IMAGES && short_header)
- print_wim_information(wimfile, w);
+ print_wim_information(wimfile, &info);
if (header)
wimlib_print_header(w);
if (lookup_table) {
- if (total_parts != 1) {
- tprintf(T("Warning: Only showing the lookup table "
- "for part %d of a %d-part WIM.\n"),
- part_number, total_parts);
+ if (info.total_parts != 1) {
+ tfprintf(stderr, T("Warning: Only showing the lookup table "
+ "for part %d of a %d-part WIM.\n"),
+ info.part_number, info.total_parts);
}
- wimlib_print_lookup_table(w);
+ print_lookup_table(w);
}
if (xml) {
} else {
tprintf(T("Marking image %d as bootable.\n"),
image);
- ret = wimlib_set_boot_idx(w, image);
+ info.boot_index = image;
+ ret = wimlib_set_wim_info(w, &info, WIMLIB_CHANGE_BOOT_INDEX);
if (ret)
goto out;
}
static int
-init_wimlib_dentry(struct wimlib_wim_dentry *wdentry,
+init_wimlib_dentry(struct wimlib_dir_entry *wdentry,
struct wim_dentry *dentry,
const WIMStruct *wim)
{
lte = inode_unnamed_lte(inode, wim->lookup_table);
if (lte)
- wdentry->streams[0].stream_size = wim_resource_size(lte);
+ lte_to_wimlib_resource_entry(lte, &wdentry->streams[0].resource);
for (unsigned i = 0; i < inode->i_num_ads; i++) {
if (inode->i_ads_entries[i].stream_name == NULL)
lte = inode_stream_lte(inode, i + 1, wim->lookup_table);
wdentry->num_named_streams++;
if (lte) {
- wdentry->streams[wdentry->num_named_streams].stream_size =
- wim_resource_size(lte);
+ lte_to_wimlib_resource_entry(lte, &wdentry->streams[
+ wdentry->num_named_streams].resource);
}
#if TCHAR_IS_UTF16LE
wdentry->streams[wdentry->num_named_streams].stream_name =
}
static void
-free_wimlib_dentry(struct wimlib_wim_dentry *wdentry)
+free_wimlib_dentry(struct wimlib_dir_entry *wdentry)
{
#if !TCHAR_IS_UTF16LE
FREE((tchar*)wdentry->filename);
void *user_ctx)
{
u32 level;
- struct wimlib_wim_dentry *wdentry;
+ struct wimlib_dir_entry *wdentry;
int ret = WIMLIB_ERR_NOMEM;
- wdentry = CALLOC(1, sizeof(struct wimlib_wim_dentry) +
+ wdentry = CALLOC(1, sizeof(struct wimlib_dir_entry) +
(1 + dentry->d_inode->i_num_ads) *
sizeof(struct wimlib_stream_entry));
if (!wdentry)
tputc(T('\n'), out);
}
+void
+lte_to_wimlib_resource_entry(const struct wim_lookup_table_entry *lte,
+ struct wimlib_resource_entry *wentry)
+{
+ wentry->uncompressed_size = lte->resource_entry.original_size;
+ wentry->compressed_size = lte->resource_entry.size;
+ wentry->offset = lte->resource_entry.offset;
+ copy_hash(wentry->sha1_hash, lte->hash);
+ wentry->part_number = lte->part_number;
+ wentry->reference_count = lte->refcnt;
+ wentry->is_compressed = (lte->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED) != 0;
+ wentry->is_metadata = (lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA) != 0;
+ wentry->is_free = (lte->resource_entry.flags & WIM_RESHDR_FLAG_FREE) != 0;
+ wentry->is_spanned = (lte->resource_entry.flags & WIM_RESHDR_FLAG_SPANNED) != 0;
+}
+
+struct iterate_lte_context {
+ wimlib_iterate_lookup_table_callback_t cb;
+ void *user_ctx;
+};
+
+static int
+do_iterate_lte(struct wim_lookup_table_entry *lte, void *_ctx)
+{
+ struct iterate_lte_context *ctx = _ctx;
+ struct wimlib_resource_entry entry;
+
+ lte_to_wimlib_resource_entry(lte, &entry);
+ return (*ctx->cb)(&entry, ctx->user_ctx);
+}
+
+WIMLIBAPI int
+wimlib_iterate_lookup_table(WIMStruct *wim, int flags,
+ wimlib_iterate_lookup_table_callback_t cb,
+ void *user_ctx)
+{
+ struct iterate_lte_context ctx = {
+ .cb = cb,
+ .user_ctx = user_ctx,
+ };
+ if (wim->hdr.part_number == 1) {
+ int ret;
+ for (int i = 0; i < wim->hdr.image_count; i++) {
+ ret = do_iterate_lte(wim->image_metadata[i]->metadata_lte,
+ &ctx);
+ if (ret)
+ return ret;
+ }
+ }
+ return for_lookup_table_entry(wim->lookup_table, do_iterate_lte, &ctx);
+}
+
static int
do_print_lookup_table_entry(struct wim_lookup_table_entry *lte, void *fp)
{
}
/*
- * Prints the lookup table of a WIM file.
+ * Deprecated
*/
WIMLIBAPI void
wimlib_print_lookup_table(WIMStruct *wim)
*lte_ret = lte;
return 0;
}
-