* Returns true if @dentry has the UTF-8 file name @name that has length
* @name_len.
*/
-static bool dentry_has_name(const struct dentry *dentry, const char *name,
+static bool dentry_has_name(const struct dentry *dentry, const char *name,
size_t name_len)
{
if (dentry->file_name_utf8_len != name_len)
}
#ifdef WITH_FUSE
-/* Transfers file attributes from a struct inode to a `stat' buffer.
+/* Transfers file attributes from a struct inode to a `stat' buffer.
*
* The lookup table entry tells us which stream in the inode we are statting.
* For a named data stream, everything returned is the same as the unnamed data
}
#endif
-/*
+/*
* Calls a function on all directory entries in a directory tree. It is called
* on a parent before its children.
*/
-int for_dentry_in_tree(struct dentry *root,
+int for_dentry_in_tree(struct dentry *root,
int (*visitor)(struct dentry*, void*), void *arg)
{
int ret;
return 0;
}
-/*
+/*
* Like for_dentry_in_tree(), but the visitor function is always called on a
* dentry's children before on itself.
*/
-int for_dentry_in_tree_depth(struct dentry *root,
+int for_dentry_in_tree_depth(struct dentry *root,
int (*visitor)(struct dentry*, void*), void *arg)
{
int ret;
return visitor(root, arg);
}
-/*
+/*
* Calculate the full path of @dentry, based on its parent's full path and on
- * its UTF-8 file name.
+ * its UTF-8 file name.
*/
int calculate_dentry_full_path(struct dentry *dentry, void *ignore)
{
return WIMLIB_ERR_NOMEM;
}
-/*
- * Recursively calculates the subdir offsets for a directory tree.
+/*
+ * Recursively calculates the subdir offsets for a directory tree.
*
* @dentry: The root of the directory tree.
* @subdir_offset_p: The current subdirectory offset; i.e., the subdirectory
- * offset for @dentry.
+ * offset for @dentry.
*/
void calculate_subdir_offsets(struct dentry *dentry, u64 *subdir_offset_p)
{
}
}
-/* Returns the child of @dentry that has the file name @name.
+/* Returns the child of @dentry that has the file name @name.
* Returns NULL if no child has the name. */
-struct dentry *get_dentry_child_with_name(const struct dentry *dentry,
+struct dentry *get_dentry_child_with_name(const struct dentry *dentry,
const char *name)
{
struct dentry *child;
size_t name_len;
-
+
child = dentry->d_inode->children;
if (child) {
name_len = strlen(name);
} else {
hash = inode_stream_hash(inode, 0);
if (hash) {
- printf("Hash = 0x");
+ printf("Hash = 0x");
print_hash(hash);
putchar('\n');
putchar('\n');
inode->ads_entries[i].stream_name_len);
hash = inode_stream_hash(inode, i + 1);
if (hash) {
- printf("Hash = 0x");
+ printf("Hash = 0x");
print_hash(hash);
putchar('\n');
}
return inode;
}
-/*
+/*
* Creates an unlinked directory entry.
*
* @name: The UTF-8 filename of the new dentry.
struct dentry *new_dentry(const char *name)
{
struct dentry *dentry;
-
+
dentry = MALLOC(sizeof(struct dentry));
if (!dentry)
goto err;
}
}
-/* Frees a WIM dentry.
+/* Frees a WIM dentry.
*
* The inode is freed only if its link count is decremented to 0.
*/
free_dentry(dentry);
}
-/*
+/*
* This function is passed as an argument to for_dentry_in_tree_depth() in order
* to free a directory tree. __args is a pointer to a `struct free_dentry_args'.
*/
return 0;
}
-/*
+/*
* Unlinks and frees a dentry tree.
*
* @root: The root of the tree.
return 0;
}
-/*
+/*
* Links a dentry into the directory tree.
*
* @dentry: The dentry to link.
#ifdef WITH_FUSE
-/*
- * Unlink a dentry from the directory tree.
+/*
+ * Unlink a dentry from the directory tree.
*
* Note: This merely removes it from the in-memory tree structure.
*/
num_unnamed_streams++;
}
if (num_unnamed_streams > 1) {
- ERROR("Dentry `%s' has multiple (%u) un-named streams",
+ ERROR("Dentry `%s' has multiple (%u) un-named streams",
first_dentry->full_path_utf8, num_unnamed_streams);
goto out;
}
#endif
#if defined(WITH_FUSE) || defined(WITH_NTFS_3G)
-/*
+/*
* Add an alternate stream entry to an inode and return a pointer to it, or NULL
* if memory could not be allocated.
*/
-/*
+/*
* Reads the alternate data stream entries for a dentry.
*
* @p: Pointer to buffer that starts with the first alternate stream entry.
*
* struct ads_entry_on_disk {
* u64 length; // Length of the entry, in bytes. This includes
- * all fields (including the stream name and
+ * all fields (including the stream name and
* null terminator if present, AND the padding!).
* u64 reserved; // Seems to be unused
* u8 hash[20]; // SHA1 message digest of the uncompressed stream
return ret;
}
-/*
+/*
* Reads a directory entry, including all alternate data stream entries that
* follow it, from the WIM image's metadata resource.
*
* special "end of directory" dentry and not a real dentry. If nonzero, this
* was a real dentry.
*/
-int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len,
+int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len,
u64 offset, struct dentry *dentry)
{
const u8 *p;
p = get_u64(p, &inode->last_write_time);
p = get_bytes(p, SHA1_HASH_SIZE, inode->hash);
-
+
/*
* I don't know what's going on here. It seems like M$ screwed up the
* reparse points, then put the fields in the same place and didn't
/* By the way, the reparse_reserved field does not actually exist (at
* least when the file is not a reparse point) */
-
+
p = get_u16(p, &inode->num_ads);
p = get_u16(p, &short_name_len);
p = get_u16(p, &file_name_len);
/* We now know the length of the file name and short name. Make sure
- * the length of the dentry is large enough to actually hold them.
+ * the length of the dentry is large enough to actually hold them.
*
* The calculated length here is unaligned to allow for the possibility
* that the dentry->length names an unaligned length, although this
if (dentry->length < calculated_size) {
ERROR("Unexpected end of directory entry! (Expected "
"at least %"PRIu64" bytes, got %"PRIu64" bytes. "
- "short_name_len = %hu, file_name_len = %hu)",
+ "short_name_len = %hu, file_name_len = %hu)",
calculated_size, dentry->length,
short_name_len, file_name_len);
return WIMLIB_ERR_INVALID_DENTRY;
p = get_bytes(p, file_name_len, file_name);
/* Convert filename to UTF-8. */
- file_name_utf8 = utf16_to_utf8(file_name, file_name_len,
+ file_name_utf8 = utf16_to_utf8(file_name, file_name_len,
&file_name_utf8_len);
if (!file_name_utf8) {
p += 2;
}
- /*
+ /*
* Read the alternate data streams, if present. dentry->num_ads tells
* us how many they are, and they will directly follow the dentry
* on-disk.
struct dentry cur_child;
int ret;
- /*
+ /*
* If @dentry has no child dentries, nothing more needs to be done for
* this branch. This is the case for regular files, symbolic links, and
* *possibly* empty directories (although an empty directory may also
while (1) {
/* Read next child of @dentry into @cur_child. */
- ret = read_dentry(metadata_resource, metadata_resource_len,
+ ret = read_dentry(metadata_resource, metadata_resource_len,
cur_offset, &cur_child);
if (ret != 0)
break;
/* If there are children of this child, call this procedure
* recursively. */
if (child->subdir_offset != 0) {
- ret = read_dentry_tree(metadata_resource,
+ ret = read_dentry_tree(metadata_resource,
metadata_resource_len, child);
if (ret != 0)
break;
return ret;
}
-/*
+/*
* Writes a WIM dentry to an output buffer.
*
* @dentry: The dentry structure.
if (parent->subdir_offset == 0)
return p;
- /* Write child dentries and end-of-directory entry.
+ /* Write child dentries and end-of-directory entry.
*
* Note: we need to write all of this dentry's children before
* recursively writing the directory trees rooted at each of the child
'M', 'S', 'W', 'I', 'M', '\0', '\0', '\0' };
/* Reads the header for a WIM file. */
-int read_header(FILE *fp, struct wim_header *hdr, int split_ok)
+int read_header(FILE *fp, struct wim_header *hdr, int open_flags)
{
size_t bytes_read;
u8 buf[WIM_HEADER_DISK_SIZE];
/* Byte 12 */
if (hdr_size != WIM_HEADER_DISK_SIZE) {
- DEBUG("ERROR: Header is size %u (expected %u)",
+ ERROR("Header is %u bytes (expected %u bytes)",
hdr_size, WIM_HEADER_DISK_SIZE);
return WIMLIB_ERR_INVALID_HEADER_SIZE;
}
p = get_u16(p, &hdr->part_number);
p = get_u16(p, &hdr->total_parts);
- if (!split_ok && (hdr->part_number != 1 || hdr->total_parts != 1)) {
+ if (!(open_flags & WIMLIB_OPEN_FLAG_SPLIT_OK)
+ && (hdr->part_number != 1 || hdr->total_parts != 1))
+ {
ERROR("This WIM is part %u of a %u-part WIM",
hdr->part_number, hdr->total_parts);
return WIMLIB_ERR_SPLIT_UNSUPPORTED;
end_lookup_table_offset = w->hdr.lookup_table_res_entry.offset +
w->hdr.lookup_table_res_entry.size;
+ if (end_lookup_table_offset < WIM_HEADER_DISK_SIZE) {
+ ERROR("WIM lookup table ends before WIM header ends???");
+ ret = WIMLIB_ERR_INVALID_INTEGRITY_TABLE;
+ goto out;
+ }
+
bytes_to_check = end_lookup_table_offset - WIM_HEADER_DISK_SIZE;
expected_num_entries = (bytes_to_check + chunk_size - 1) / chunk_size;
struct lookup_table_entry *lte;
lte = CALLOC(1, sizeof(struct lookup_table_entry));
- if (!lte) {
+ if (lte) {
+ lte->part_number = 1;
+ lte->refcnt = 1;
+ } else {
ERROR("Out of memory (tried to allocate %zu bytes for "
"lookup table entry)",
sizeof(struct lookup_table_entry));
- return NULL;
}
-
- lte->part_number = 1;
- lte->refcnt = 1;
return lte;
}
w->hdr.lookup_table_res_entry.offset,
w->hdr.lookup_table_res_entry.original_size);
- if (fseeko(w->fp, w->hdr.lookup_table_res_entry.offset, SEEK_SET) != 0) {
+ if (fseeko(w->fp, w->hdr.lookup_table_res_entry.offset, SEEK_SET) != 0)
+ {
ERROR_WITH_ERRNO("Failed to seek to byte %"PRIu64" to read "
"lookup table",
w->hdr.lookup_table_res_entry.offset);
w->hdr.part_number, cur_entry->part_number);
ret = WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY;
goto out_free_cur_entry;
-
}
if (is_zero_hash(cur_entry->hash)) {
if (!(cur_entry->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED)
&& (cur_entry->resource_entry.size !=
- cur_entry->resource_entry.original_size))
+ cur_entry->resource_entry.original_size))
{
ERROR("Found uncompressed resource with original size "
"not the same as compressed size");
lookup_table_remove(lt, imd->metadata_lte);
}
-/*
+/*
* Recursively builds a dentry tree from a directory tree on disk, outside the
* WIM file.
*
* modified if successful. NULL if the file or directory was
* excluded from capture.
*
- * @root_disk_path: The path to the root of the directory tree on disk.
+ * @root_disk_path: The path to the root of the directory tree on disk.
*
* @lookup_table: The lookup table for the WIM file. For each file added to the
- * dentry tree being built, an entry is added to the lookup table,
+ * dentry tree being built, an entry is added to the lookup table,
* unless an identical stream is already in the lookup table.
* These lookup table entries that are added point to the path of
* the file on disk.
return WIMLIB_ERR_STAT;
}
- if ((add_flags & WIMLIB_ADD_IMAGE_FLAG_ROOT) &&
+ if ((add_flags & WIMLIB_ADD_IMAGE_FLAG_ROOT) &&
!S_ISDIR(root_stbuf.st_mode)) {
ERROR("`%s' is not a directory", root_disk_path);
return WIMLIB_ERR_NOTDIR;
} else if (dentry_is_symlink(root)) { /* Archiving a symbolic link */
char deref_name_buf[4096];
ssize_t deref_name_len;
-
+
deref_name_len = readlink(root_disk_path, deref_name_buf,
sizeof(deref_name_buf) - 1);
if (deref_name_len >= 0) {
return 0;
}
-/*
+/*
* This function takes in a dentry that was previously located only in image(s)
* in @src_wim, but now is being added to @dest_wim. For each stream associated
* with the dentry, if there is already a lookup table entry for that stream in
/*
* Adds an image (given by its dentry tree) to the image metadata array of a WIM
* file, adds an entry to the lookup table for the image metadata, updates the
- * image count in the header, and selects the new image.
+ * image count in the header, and selects the new image.
*
* Does not update the XML data.
*
return WIMLIB_ERR_NOMEM;
}
- memcpy(imd, w->image_metadata,
+ memcpy(imd, w->image_metadata,
w->hdr.image_count * sizeof(struct image_metadata));
-
+
metadata_lte = new_lookup_table_entry();
if (!metadata_lte)
goto out_free_imd;
/*
* Copies an image, or all the images, from a WIM file, into another WIM file.
*/
-WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim,
- int src_image,
- WIMStruct *dest_wim,
- const char *dest_name,
- const char *dest_description,
+WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim,
+ int src_image,
+ WIMStruct *dest_wim,
+ const char *dest_name,
+ const char *dest_description,
int flags,
WIMStruct **additional_swms,
unsigned num_additional_swms)
/* multi-image export. */
- if ((flags & WIMLIB_EXPORT_FLAG_BOOT) &&
+ if ((flags & WIMLIB_EXPORT_FLAG_BOOT) &&
(src_wim->hdr.boot_idx == 0))
{
/* Specifying the boot flag on a multi-image
if (i != src_wim->hdr.boot_idx)
export_flags &= ~WIMLIB_EXPORT_FLAG_BOOT;
- ret = wimlib_export_image(src_wim, i, dest_wim,
+ ret = wimlib_export_image(src_wim, i, dest_wim,
NULL, NULL,
export_flags,
additional_swms,
return ret;
}
return 0;
+ } else if (src_wim->hdr.image_count == 1) {
+ src_image = 1;
} else {
- src_image = 1;
+ return 0;
}
}
return ret;
}
-/*
- * Deletes an image from the WIM.
+/*
+ * Deletes an image from the WIM.
*/
WIMLIBAPI int wimlib_delete_image(WIMStruct *w, int image)
{
FREE(config_str);
return WIMLIB_ERR_NOMEM;
}
-
+
memcpy(config_str, _config_str, config_len);
next_p = config_str;
config->config_str = config_str;
ret = WIMLIB_ERR_INVALID_CAPTURE_CONFIG;
goto out_destroy;
}
-
+
next_p = eol + 1;
bytes_remaining -= (next_p - p);
if (eol == p)
&& path[config->prefix_len] == '/')
path += config->prefix_len;
}
- return match_pattern(path, basename, &config->exclusion_list) &&
+ return match_pattern(path, basename, &config->exclusion_list) &&
!match_pattern(path, basename, &config->exclusion_exception);
}
const char *config_str, size_t config_len,
int flags,
int (*capture_tree)(struct dentry **, const char *,
- struct lookup_table *,
+ struct lookup_table *,
struct wim_security_data *,
const struct capture_config *,
int, void *),
/*
* Adds an image to a WIM file from a directory tree on disk.
*/
-WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *dir,
+WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *dir,
const char *name, const char *config_str,
size_t config_len, int flags)
{
p = get_u8(p, &flags);
entry->size = size;
entry->flags = flags;
+
+ /* offset and original_size are truncated to 62 bits to avoid possible
+ * overflows, when converting to a signed 64-bit integer (off_t) or when
+ * adding size or original_size. This is okay since no one would ever
+ * actually have a WIM bigger than 4611686018427387903 bytes... */
p = get_u64(p, &entry->offset);
+ if (entry->offset & 0xc000000000000000ULL) {
+ WARNING("Truncating offset in resource entry");
+ entry->offset &= 0x3fffffffffffffffULL;
+ }
p = get_u64(p, &entry->original_size);
+ if (entry->original_size & 0xc000000000000000ULL) {
+ WARNING("Truncating original_size in resource entry");
+ entry->original_size &= 0x3fffffffffffffffULL;
+ }
return p;
}
*/
void print_security_data(const struct wim_security_data *sd)
{
+ wimlib_assert(sd != NULL);
+
puts("[SECURITY DATA]");
printf("Length = %"PRIu32" bytes\n", sd->total_length);
printf("Number of Entries = %"PRIu32"\n", sd->num_entries);
}
static const char *error_strings[] = {
- [WIMLIB_ERR_SUCCESS]
+ [WIMLIB_ERR_SUCCESS]
= "Success",
- [WIMLIB_ERR_COMPRESSED_LOOKUP_TABLE]
+ [WIMLIB_ERR_COMPRESSED_LOOKUP_TABLE]
= "Lookup table is compressed",
- [WIMLIB_ERR_DECOMPRESSION]
+ [WIMLIB_ERR_DECOMPRESSION]
= "Failed to decompress compressed data",
- [WIMLIB_ERR_DELETE_STAGING_DIR]
+ [WIMLIB_ERR_DELETE_STAGING_DIR]
= "Failed to delete staging directory",
- [WIMLIB_ERR_FORK]
+ [WIMLIB_ERR_FORK]
= "Failed to fork another process",
- [WIMLIB_ERR_FUSE]
+ [WIMLIB_ERR_FUSE]
= "An error was returned by fuse_main()",
- [WIMLIB_ERR_FUSERMOUNT]
+ [WIMLIB_ERR_FUSERMOUNT]
= "Could not execute the `fusermount' program, or it exited "
"with a failure status",
- [WIMLIB_ERR_IMAGE_COUNT]
+ [WIMLIB_ERR_IMAGE_COUNT]
= "Inconsistent image count among the metadata "
"resources, the WIM header, and/or the XML data",
- [WIMLIB_ERR_IMAGE_NAME_COLLISION]
+ [WIMLIB_ERR_IMAGE_NAME_COLLISION]
= "Tried to add an image with a name that is already in use",
- [WIMLIB_ERR_INTEGRITY]
+ [WIMLIB_ERR_INTEGRITY]
= "The WIM failed an integrity check",
[WIMLIB_ERR_INVALID_CAPTURE_CONFIG]
= "The capture configuration string was invalid",
- [WIMLIB_ERR_INVALID_CHUNK_SIZE]
+ [WIMLIB_ERR_INVALID_CHUNK_SIZE]
= "The WIM is compressed but does not have a chunk "
"size of 32768",
- [WIMLIB_ERR_INVALID_COMPRESSION_TYPE]
+ [WIMLIB_ERR_INVALID_COMPRESSION_TYPE]
= "The WIM is compressed, but is not marked as having LZX or "
"XPRESS compression",
- [WIMLIB_ERR_INVALID_DENTRY]
+ [WIMLIB_ERR_INVALID_DENTRY]
= "A directory entry in the WIM was invalid",
- [WIMLIB_ERR_INVALID_HEADER_SIZE]
+ [WIMLIB_ERR_INVALID_HEADER_SIZE]
= "The WIM header was not 208 bytes",
- [WIMLIB_ERR_INVALID_IMAGE]
+ [WIMLIB_ERR_INVALID_IMAGE]
= "Tried to select an image that does not exist in the WIM",
- [WIMLIB_ERR_INVALID_INTEGRITY_TABLE]
+ [WIMLIB_ERR_INVALID_INTEGRITY_TABLE]
= "The WIM's integrity table is invalid",
[WIMLIB_ERR_INVALID_LOOKUP_TABLE_ENTRY]
= "An entry in the WIM's lookup table is invalid",
- [WIMLIB_ERR_INVALID_PARAM]
+ [WIMLIB_ERR_INVALID_PARAM]
= "An invalid parameter was given",
[WIMLIB_ERR_INVALID_RESOURCE_HASH]
= "The SHA1 message digest of a WIM resource did not match the expected value",
- [WIMLIB_ERR_INVALID_RESOURCE_SIZE]
- = "A resource entry in the WIM is invalid",
- [WIMLIB_ERR_LINK]
+ [WIMLIB_ERR_INVALID_RESOURCE_SIZE]
+ = "A resource entry in the WIM has an invalid size",
+ [WIMLIB_ERR_LINK]
= "Failed to create a hard or symbolic link when extracting "
"a file from the WIM",
- [WIMLIB_ERR_MKDIR]
+ [WIMLIB_ERR_MKDIR]
= "Failed to create a directory",
- [WIMLIB_ERR_MQUEUE]
+ [WIMLIB_ERR_MQUEUE]
= "Failed to create or use a POSIX message queue",
- [WIMLIB_ERR_NOMEM]
+ [WIMLIB_ERR_NOMEM]
= "Ran out of memory",
- [WIMLIB_ERR_NOTDIR]
+ [WIMLIB_ERR_NOTDIR]
= "Expected a directory",
- [WIMLIB_ERR_NOT_A_WIM_FILE]
+ [WIMLIB_ERR_NOT_A_WIM_FILE]
= "The file did not begin with the magic characters that "
"identify a WIM file",
- [WIMLIB_ERR_NO_FILENAME]
+ [WIMLIB_ERR_NO_FILENAME]
= "The WIM is not identified with a filename",
[WIMLIB_ERR_NTFS_3G]
= "NTFS-3g encountered an error (check errno)",
- [WIMLIB_ERR_OPEN]
+ [WIMLIB_ERR_OPEN]
= "Failed to open a file",
- [WIMLIB_ERR_OPENDIR]
+ [WIMLIB_ERR_OPENDIR]
= "Failed to open a directory",
- [WIMLIB_ERR_READ]
+ [WIMLIB_ERR_READ]
= "Could not read data from a file",
[WIMLIB_ERR_READLINK]
= "Could not read the target of a symbolic link",
- [WIMLIB_ERR_RENAME]
+ [WIMLIB_ERR_RENAME]
= "Could not rename a file",
[WIMLIB_ERR_SPECIAL_FILE]
= "Encountered a special file that cannot be archived",
- [WIMLIB_ERR_SPLIT_INVALID]
+ [WIMLIB_ERR_SPLIT_INVALID]
= "The WIM is part of an invalid split WIM",
- [WIMLIB_ERR_SPLIT_UNSUPPORTED]
+ [WIMLIB_ERR_SPLIT_UNSUPPORTED]
= "The WIM is part of a split WIM, which is not supported for this operation",
- [WIMLIB_ERR_STAT]
+ [WIMLIB_ERR_STAT]
= "Could not read the metadata for a file or directory",
- [WIMLIB_ERR_TIMEOUT]
+ [WIMLIB_ERR_TIMEOUT]
= "Timed out",
- [WIMLIB_ERR_UNKNOWN_VERSION]
+ [WIMLIB_ERR_UNKNOWN_VERSION]
= "The WIM file is marked with an unknown version number",
- [WIMLIB_ERR_UNSUPPORTED]
+ [WIMLIB_ERR_UNSUPPORTED]
= "The requested operation is unsupported",
- [WIMLIB_ERR_WRITE]
+ [WIMLIB_ERR_WRITE]
= "Failed to write data to a file",
- [WIMLIB_ERR_XML]
+ [WIMLIB_ERR_XML]
= "The XML data of the WIM is invalid",
};
{
size_t size;
char *p;
-
- size = strlen(str);
+
+ size = strlen(str);
p = MALLOC(size + 1);
if (p)
memcpy(p, str, size + 1);
wimlib_free_func = free_func ? free_func : free;
wimlib_realloc_func = realloc_func ? realloc_func : realloc;
- xml_set_memory_allocator(wimlib_malloc_func, wimlib_free_func,
+ xml_set_memory_allocator(wimlib_malloc_func, wimlib_free_func,
wimlib_realloc_func);
return 0;
#else
char *orig_utf8_str = utf8_str;
- size_t num_chars_converted = iconv(cd_utf16_to_utf8, (char**)&utf16_str,
+ size_t num_chars_converted = iconv(cd_utf16_to_utf8, (char**)&utf16_str,
&utf16_bytes_left, &utf8_str, &utf8_bytes_left);
if (num_chars_converted == (size_t)(-1)) {
char *orig_utf16_str = utf16_str;
- size_t num_chars_converted = iconv(cd_utf8_to_utf16, (char**)&utf8_str,
+ size_t num_chars_converted = iconv(cd_utf8_to_utf16, (char**)&utf8_str,
&utf8_bytes_left, &utf16_str, &utf16_bytes_left);
if (num_chars_converted == (size_t)(-1)) {
return p + 1;
}
-/*
+/*
* Returns a pointer to the part of @path following the first colon in the last
* path component, or NULL if the last path component does not contain a colon.
*/
return stream_name + 1;
}
-/*
+/*
* Splits a file path into the part before the first '/', or the entire name if
* there is no '/', and the part after the first sequence of '/' characters.
*
* @first_part_len_ret: A pointer to a `size_t' into which the length of the
* first part of the path will be returned.
* @return: A pointer to the next part of the path, after the first
- * sequence of '/', or a pointer to the terminating
+ * sequence of '/', or a pointer to the terminating
* null byte in the case of a path without any '/'.
*/
const char *path_next_part(const char *path, size_t *first_part_len_ret)
}
-/*
+/*
* Prints a string. Printable characters are printed as-is, while unprintable
- * characters are printed as their octal escape codes.
+ * characters are printed as their octal escape codes.
*/
void print_string(const void *string, size_t len)
{
* Copyright (C) 2010 Carl Thijssen
* Copyright (C) 2012 Eric Biggers
*
- * wimlib - Library for working with WIM files
+ * wimlib - Library for working with WIM files
*
* This file is part of wimlib, a library for working with WIM files.
*
static int print_metadata(WIMStruct *w)
{
+ DEBUG("Printing metadata for image %d", w->current_image);
print_security_data(wim_security_data(w));
- return for_dentry_in_tree(wim_root_dentry(w), print_dentry,
+ return for_dentry_in_tree(wim_root_dentry(w), print_dentry,
w->lookup_table);
}
static int print_files(WIMStruct *w)
{
- return for_dentry_in_tree(wim_root_dentry(w), print_dentry_full_path,
+ return for_dentry_in_tree(wim_root_dentry(w), print_dentry_full_path,
NULL);
}
return CALLOC(1, sizeof(WIMStruct));
}
-/*
+/*
* Calls a function on images in the WIM. If @image is WIM_ALL_IMAGES, @visitor
* is called on the WIM once for each image, with each image selected as the
* current image in turn. If @image is a certain image, @visitor is called on
int for_image(WIMStruct *w, int image, int (*visitor)(WIMStruct *))
{
int ret;
- int i;
+ int start;
int end;
+ int i;
if (image == WIM_ALL_IMAGES) {
- i = 1;
+ start = 1;
end = w->hdr.image_count;
- } else {
- if (image < 1 || image > w->hdr.image_count)
- return WIMLIB_ERR_INVALID_IMAGE;
- i = image;
+ } else if (image >= 1 && image <= w->hdr.image_count) {
+ start = image;
end = image;
+ } else {
+ return WIMLIB_ERR_INVALID_IMAGE;
}
- for (; i <= end; i++) {
+ for (i = start; i <= end; i++) {
ret = select_wim_image(w, i);
if (ret != 0)
return ret;
static int sort_image_metadata_by_position(const void *p1, const void *p2)
{
- struct image_metadata *bmd1 = (struct image_metadata*)p1;
- struct image_metadata *bmd2 = (struct image_metadata*)p2;
- u64 offset1 = bmd1->metadata_lte->resource_entry.offset;
- u64 offset2 = bmd2->metadata_lte->resource_entry.offset;
+ const struct image_metadata *imd1 = p1;
+ const struct image_metadata *imd2 = p2;
+ u64 offset1 = imd1->metadata_lte->resource_entry.offset;
+ u64 offset2 = imd2->metadata_lte->resource_entry.offset;
if (offset1 < offset2)
return -1;
else if (offset1 > offset2)
return 0;
}
-/*
+/*
* If @lte points to a metadata resource, append it to the list of metadata
* resources in the WIMStruct. Otherwise, do nothing.
*/
-static int append_metadata_resource_entry(struct lookup_table_entry *lte,
+static int append_metadata_resource_entry(struct lookup_table_entry *lte,
void *wim_p)
{
WIMStruct *w = wim_p;
+ int ret = 0;
if (lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA) {
- /*fprintf(stderr, "found mlte at %u\n", lte->resource_entry.offset);*/
if (w->current_image == w->hdr.image_count) {
ERROR("Expected only %u images, but found more",
w->hdr.image_count);
- return WIMLIB_ERR_IMAGE_COUNT;
+ ret = WIMLIB_ERR_IMAGE_COUNT;
} else {
DEBUG("Found metadata resource for image %u at "
"offset %"PRIu64".",
- w->current_image + 1,
+ w->current_image + 1,
lte->resource_entry.offset);
w->image_metadata[
w->current_image++].metadata_lte = lte;
}
}
- return 0;
+ return ret;
}
/* Returns the compression type given in the flags of a WIM header. */
WIMLIBAPI void wimlib_print_wim_information(const WIMStruct *w)
{
const struct wim_header *hdr;
-
+
hdr = &w->hdr;
puts("WIM Information:");
puts("----------------");
wimlib_get_compression_type(w)));
printf("Part Number: %d/%d\n", hdr->part_number, hdr->total_parts);
printf("Boot Index: %d\n", hdr->boot_idx);
- printf("Size: %"PRIu64" bytes\n",
+ printf("Size: %"PRIu64" bytes\n",
wim_info_get_total_bytes(w->wim_info));
printf("Integrity Info: %s\n", (w->hdr.integrity.size != 0) ? "yes" : "no");
putchar('\n');
WIMLIBAPI void wimlib_print_available_images(const WIMStruct *w, int image)
{
+ int first;
+ int last;
+ int i;
+ int n;
if (image == WIM_ALL_IMAGES) {
- puts("Available Images:");
- puts("-----------------");
- } else {
- int n;
- int i;
-
+ n = printf("Available Images:\n");
+ first = 1;
+ last = w->hdr.image_count;
+ } else if (image >= 1 && image <= w->hdr.image_count) {
n = printf("Information for Image %d\n", image);
- for (i = 0; i < n - 1; i++)
- putchar('-');
- putchar('\n');
-
+ first = image;
+ last = image;
+ } else {
+ printf("wimlib_print_available_images(): Invalid image %d",
+ image);
+ return;
}
- print_image_info(w->wim_info, image);
+ for (i = 0; i < n - 1; i++)
+ putchar('-');
+ putchar('\n');
+ for (i = first; i <= last; i++)
+ print_image_info(w->wim_info, i);
}
if (!w)
return WIMLIB_ERR_INVALID_PARAM;
if (w->hdr.part_number != 1) {
- ERROR("We cannot show the metadata from part %hu of a %hu-part split WIM.",
+ ERROR("Cannot show the metadata from part %hu of a %hu-part split WIM!",
w->hdr.part_number, w->hdr.total_parts);
ERROR("Select the first part of the split WIM to see the metadata.");
return WIMLIB_ERR_SPLIT_UNSUPPORTED;
}
- if (image == WIM_ALL_IMAGES)
- DEBUG("Printing metadata for all images");
- else
- DEBUG("Printing metadata for image %d", image);
return for_image(w, image, print_metadata);
}
if (!w)
return WIMLIB_ERR_INVALID_PARAM;
if (w->hdr.part_number != 1) {
- ERROR("We cannot list the files from part %hu of a %hu-part split WIM",
+ ERROR("Cannot list the files from part %hu of a %hu-part split WIM!",
w->hdr.part_number, w->hdr.total_parts);
ERROR("Select the first part of the split WIM if you'd like to list the files.");
return WIMLIB_ERR_SPLIT_UNSUPPORTED;
if (!w)
return WIMLIB_ERR_INVALID_PARAM;
if (w->hdr.total_parts != 1) {
- ERROR("We cannot modify the boot index of a split WIM");
+ ERROR("Cannot modify the boot index of a split WIM!");
return WIMLIB_ERR_SPLIT_UNSUPPORTED;
}
if (boot_idx < 0 || boot_idx > w->hdr.image_count)
return WIMLIB_ERR_INVALID_IMAGE;
w->hdr.boot_idx = boot_idx;
- if (boot_idx == 0) {
- memset(&w->hdr.boot_metadata_res_entry, 0,
- sizeof(struct resource_entry));
- } else {
- memcpy(&w->hdr.boot_metadata_res_entry,
- &w->image_metadata[
- boot_idx - 1].metadata_lte->resource_entry,
- sizeof(struct resource_entry));
- }
return 0;
}
*total_parts_ret = w->hdr.total_parts;
return w->hdr.part_number;
}
-
+
WIMLIBAPI int wimlib_get_boot_idx(const WIMStruct *w)
{
return w->hdr.boot_idx;
}
-/*
+/*
* Begins the reading of a WIM file; opens the file and reads its header and
* lookup table, and optionally checks the integrity.
*/
-static int begin_read(WIMStruct *w, const char *in_wim_path, int flags)
+static int begin_read(WIMStruct *w, const char *in_wim_path, int open_flags)
{
int ret;
uint xml_num_images;
return WIMLIB_ERR_OPEN;
}
- ret = read_header(w->fp, &w->hdr, flags & WIMLIB_OPEN_FLAG_SPLIT_OK);
+ ret = read_header(w->fp, &w->hdr, open_flags);
if (ret != 0)
return ret;
/* If the boot index is invalid, print a warning and set it to 0 */
if (w->hdr.boot_idx > w->hdr.image_count) {
WARNING("In `%s', image %u is marked as bootable, "
- "but there are only %u images",
- in_wim_path, w->hdr.boot_idx, w->hdr.image_count);
+ "but there are only %u images in the WIM",
+ in_wim_path, w->hdr.boot_idx, w->hdr.image_count);
w->hdr.boot_idx = 0;
}
}
- if (flags & WIMLIB_OPEN_FLAG_CHECK_INTEGRITY) {
+ if (open_flags & WIMLIB_OPEN_FLAG_CHECK_INTEGRITY) {
int integrity_status;
- ret = check_wim_integrity(w,
- flags & WIMLIB_OPEN_FLAG_SHOW_PROGRESS,
+ ret = check_wim_integrity(w,
+ open_flags & WIMLIB_OPEN_FLAG_SHOW_PROGRESS,
&integrity_status);
- if (ret != 0) {
- ERROR("Error in check_wim_integrity()");
+ if (ret != 0)
return ret;
- }
if (integrity_status == WIM_INTEGRITY_NONEXISTENT) {
WARNING("No integrity information for `%s'; skipping "
"integrity check.", w->filename);
if (ret != 0)
return ret;
- w->image_metadata = CALLOC(w->hdr.image_count,
+ w->image_metadata = CALLOC(w->hdr.image_count,
sizeof(struct image_metadata));
if (!w->image_metadata) {
DEBUG("Looking for metadata resources in the lookup table.");
/* Find the images in the WIM by searching the lookup table. */
- ret = for_lookup_table_entry(w->lookup_table,
+ ret = for_lookup_table_entry(w->lookup_table,
append_metadata_resource_entry, w);
if (ret != 0)
/* Make sure all the expected images were found. (We already have
* returned false if *extra* images were found) */
- if (w->current_image != w->hdr.image_count && w->hdr.part_number == 1) {
+ if (w->current_image != w->hdr.image_count &&
+ w->hdr.part_number == 1)
+ {
ERROR("Only found %u images in WIM, but expected %u",
w->current_image, w->hdr.image_count);
return WIMLIB_ERR_IMAGE_COUNT;
w->current_image = WIM_NO_IMAGE;
/* Read the XML data. */
- ret = read_xml_data(w->fp, &w->hdr.xml_res_entry,
+ ret = read_xml_data(w->fp, &w->hdr.xml_res_entry,
&w->xml_data, &w->wim_info);
if (ret != 0) {
/*
* Opens a WIM file and creates a WIMStruct for it.
*/
-WIMLIBAPI int wimlib_open_wim(const char *wim_file, int flags,
+WIMLIBAPI int wimlib_open_wim(const char *wim_file, int open_flags,
WIMStruct **w_ret)
{
WIMStruct *w;
int ret;
- DEBUG("wim_file = `%s', flags = %#x", wim_file, flags);
+ DEBUG("wim_file = `%s', open_flags = %#x", wim_file, open_flags);
w = new_wim_struct();
if (!w) {
ERROR("Failed to allocate memory for WIMStruct");
return WIMLIB_ERR_NOMEM;
}
- ret = begin_read(w, wim_file, flags);
- if (ret != 0) {
+ ret = begin_read(w, wim_file, open_flags);
+ if (ret == 0) {
+ *w_ret = w;
+ } else {
DEBUG("Could not begin reading the WIM file `%s'", wim_file);
wimlib_free(w);
- return ret;
}
- *w_ret = w;
- return 0;
+ return ret;
}
/* Frees the memory for the WIMStruct, including all internal memory; also
* image, or ::WIM_ALL_IMAGES to print information about all images in the
* WIM.
*
- * @return This function has no return value.
+ * @return This function has no return value. No error checking is done when
+ * printing the information. If @a image is invalid, an error message is
+ * printed.
*/
extern void wimlib_print_available_images(const WIMStruct *wim, int image);
/* Reads the information from a <VERSION> element inside the <WINDOWS> element.
* */
-static void xml_read_windows_version(const xmlNode *version_node,
+static void xml_read_windows_version(const xmlNode *version_node,
struct windows_version* windows_version)
{
xmlNode *child;
/* Reads the information from a <LANGUAGE> element inside a <WINDOWS> element.
* */
-static int xml_read_languages(const xmlNode *languages_node,
- char ***languages_ret,
+static int xml_read_languages(const xmlNode *languages_node,
+ char ***languages_ret,
u64 *num_languages_ret,
char **default_language_ret)
{
}
/* Reads the information from a <WINDOWS> element inside an <IMAGE> element. */
-static int xml_read_windows_info(const xmlNode *windows_node,
+static int xml_read_windows_info(const xmlNode *windows_node,
struct windows_info *windows_info)
{
xmlNode *child;
if (node_name_is(child, "ARCH")) {
windows_info->arch = node_get_u64(child);
} else if (node_name_is(child, "PRODUCTNAME")) {
- ret = node_get_string(child,
+ ret = node_get_string(child,
&windows_info->product_name);
} else if (node_name_is(child, "EDITIONID")) {
- ret = node_get_string(child,
+ ret = node_get_string(child,
&windows_info->edition_id);
} else if (node_name_is(child, "INSTALLATIONTYPE")) {
- ret = node_get_string(child,
+ ret = node_get_string(child,
&windows_info->installation_type);
} else if (node_name_is(child, "PRODUCTTYPE")) {
- ret = node_get_string(child,
+ ret = node_get_string(child,
&windows_info->product_type);
} else if (node_name_is(child, "PRODUCTSUITE")) {
- ret = node_get_string(child,
+ ret = node_get_string(child,
&windows_info->product_suite);
} else if (node_name_is(child, "LANGUAGES")) {
- ret = xml_read_languages(child,
+ ret = xml_read_languages(child,
&windows_info->languages,
&windows_info->num_languages,
&windows_info->default_language);
} else if (node_name_is(child, "VERSION")) {
- xml_read_windows_version(child,
+ xml_read_windows_version(child,
&windows_info->windows_version);
windows_info->windows_version_exists = true;
} else if (node_name_is(child, "SYSTEMROOT")) {
}
/* Reads the information from an <IMAGE> element. */
-static int xml_read_image_info(xmlNode *image_node,
+static int xml_read_image_info(xmlNode *image_node,
struct image_info *image_info)
{
xmlNode *child;
xmlChar *index_prop;
int ret;
-
+
index_prop = xmlGetProp(image_node, "INDEX");
if (index_prop) {
char *tmp;
}
/* Sort the array of struct image_infos by image index. */
- qsort(wim_info->images, wim_info->num_images,
+ qsort(wim_info->images, wim_info->num_images,
sizeof(struct image_info), sort_by_index);
done:
*wim_info_ret = wim_info;
const struct windows_version *windows_version;
printf("Architecture: %s\n", get_arch(windows_info->arch));
- printf("Product Name: %s\n", windows_info->product_name);
- printf("Edition ID: %s\n", windows_info->edition_id);
- printf("Installation Type: %s\n", windows_info->installation_type);
+
+ if (windows_info->product_name)
+ printf("Product Name: %s\n",
+ windows_info->product_name);
+
+ if (windows_info->edition_id)
+ printf("Edition ID: %s\n",
+ windows_info->edition_id);
+
+ if (windows_info->installation_type)
+ printf("Installation Type: %s\n",
+ windows_info->installation_type);
+
if (windows_info->hal)
printf("HAL: %s\n", windows_info->hal);
- printf("Product Type: %s\n", windows_info->product_type);
+
+ if (windows_info->product_type)
+ printf("Product Type: %s\n",
+ windows_info->product_type);
+
if (windows_info->product_suite)
- printf("Product Suite: %s\n", windows_info->product_suite);
+ printf("Product Suite: %s\n",
+ windows_info->product_suite);
printf("Languages: ");
for (i = 0; i < windows_info->num_languages; i++) {
fputs(windows_info->languages[i], stdout);
putchar(' ');
}
putchar('\n');
- printf("Default Language: %s\n", windows_info->default_language);
- printf("System Root: %s\n", windows_info->system_root);
+ if (windows_info->default_language)
+ printf("Default Language: %s\n",
+ windows_info->default_language);
+ if (windows_info->system_root)
+ printf("System Root: %s\n",
+ windows_info->system_root);
if (windows_info->windows_version_exists) {
windows_version = &windows_info->windows_version;
- printf("Major Version: %"PRIu64"\n",
+ printf("Major Version: %"PRIu64"\n",
windows_version->major);
- printf("Minor Version: %"PRIu64"\n",
+ printf("Minor Version: %"PRIu64"\n",
windows_version->minor);
- printf("Build: %"PRIu64"\n",
+ printf("Build: %"PRIu64"\n",
windows_version->build);
- printf("Service Pack Build: %"PRIu64"\n",
+ printf("Service Pack Build: %"PRIu64"\n",
windows_version->sp_build);
- printf("Service Pack Level: %"PRIu64"\n",
+ printf("Service Pack Level: %"PRIu64"\n",
windows_version->sp_level);
}
}
/* Writes the information contained in a struct windows_version structure to the XML
* document being constructed in memory. This is the <VERSION> element inside
* the <WINDOWS> element. */
-static int xml_write_windows_version(xmlTextWriter *writer,
- const struct windows_version *version)
+static int xml_write_windows_version(xmlTextWriter *writer,
+ const struct windows_version *version)
{
int rc;
rc = xmlTextWriterStartElement(writer, "VERSION");
if (rc < 0)
return rc;
- rc = xmlTextWriterWriteFormatElement(writer, "MAJOR", "%"PRIu64,
+ rc = xmlTextWriterWriteFormatElement(writer, "MAJOR", "%"PRIu64,
version->major);
if (rc < 0)
return rc;
- rc = xmlTextWriterWriteFormatElement(writer, "MINOR", "%"PRIu64,
+ rc = xmlTextWriterWriteFormatElement(writer, "MINOR", "%"PRIu64,
version->minor);
if (rc < 0)
return rc;
- rc = xmlTextWriterWriteFormatElement(writer, "BUILD", "%"PRIu64,
+ rc = xmlTextWriterWriteFormatElement(writer, "BUILD", "%"PRIu64,
version->build);
if (rc < 0)
return rc;
- rc = xmlTextWriterWriteFormatElement(writer, "SPBUILD", "%"PRIu64,
+ rc = xmlTextWriterWriteFormatElement(writer, "SPBUILD", "%"PRIu64,
version->sp_build);
if (rc < 0)
return rc;
- rc = xmlTextWriterWriteFormatElement(writer, "SPLEVEL", "%"PRIu64,
+ rc = xmlTextWriterWriteFormatElement(writer, "SPLEVEL", "%"PRIu64,
version->sp_level);
if (rc < 0)
return rc;
/* Writes the information contained in a struct windows_info structure to the XML
* document being constructed in memory. This is the <WINDOWS> element. */
-static int xml_write_windows_info(xmlTextWriter *writer,
- const struct windows_info *windows_info)
+static int xml_write_windows_info(xmlTextWriter *writer,
+ const struct windows_info *windows_info)
{
int rc;
rc = xmlTextWriterStartElement(writer, "WINDOWS");
return rc;
- rc = xmlTextWriterWriteFormatElement(writer, "ARCH", "%"PRIu64,
+ rc = xmlTextWriterWriteFormatElement(writer, "ARCH", "%"PRIu64,
windows_info->arch);
if (rc < 0)
return rc;
-
+
if (windows_info->product_name) {
- rc = xmlTextWriterWriteElement(writer, "PRODUCTNAME",
+ rc = xmlTextWriterWriteElement(writer, "PRODUCTNAME",
windows_info->product_name);
if (rc < 0)
return rc;
}
if (windows_info->edition_id) {
- rc = xmlTextWriterWriteElement(writer, "EDITIONID",
+ rc = xmlTextWriterWriteElement(writer, "EDITIONID",
windows_info->edition_id);
if (rc < 0)
return rc;
}
if (windows_info->installation_type) {
- rc = xmlTextWriterWriteElement(writer, "INSTALLATIONTYPE",
+ rc = xmlTextWriterWriteElement(writer, "INSTALLATIONTYPE",
windows_info->installation_type);
if (rc < 0)
return rc;
}
if (windows_info->hal) {
- rc = xmlTextWriterWriteElement(writer, "HAL",
+ rc = xmlTextWriterWriteElement(writer, "HAL",
windows_info->hal);
if (rc < 0)
return rc;
}
if (windows_info->system_root) {
- rc = xmlTextWriterWriteElement(writer, "SYSTEMROOT",
+ rc = xmlTextWriterWriteElement(writer, "SYSTEMROOT",
windows_info->system_root);
if (rc < 0)
return rc;
}
if (windows_info->product_type) {
- rc = xmlTextWriterWriteElement(writer, "PRODUCTTYPE",
+ rc = xmlTextWriterWriteElement(writer, "PRODUCTTYPE",
windows_info->product_type);
if (rc < 0)
return rc;
}
if (windows_info->product_suite) {
- rc = xmlTextWriterWriteElement(writer, "PRODUCTSUITE",
+ rc = xmlTextWriterWriteElement(writer, "PRODUCTSUITE",
windows_info->product_suite);
if (rc < 0)
return rc;
return rc;
for (int i = 0; i < windows_info->num_languages; i++) {
- rc = xmlTextWriterWriteElement(writer, "LANGUAGE",
+ rc = xmlTextWriterWriteElement(writer, "LANGUAGE",
windows_info->languages[i]);
if (rc < 0)
return rc;
}
- rc = xmlTextWriterWriteElement(writer, "DEFAULT",
+ rc = xmlTextWriterWriteElement(writer, "DEFAULT",
windows_info->default_language);
if (rc < 0)
return rc;
}
/* Writes a time element to the XML document being constructed in memory. */
-static int xml_write_time(xmlTextWriter *writer, const char *element_name,
- u64 time)
+static int xml_write_time(xmlTextWriter *writer, const char *element_name,
+ u64 time)
{
int rc;
rc = xmlTextWriterStartElement(writer, element_name);
if (rc < 0)
return rc;
- rc = xmlTextWriterWriteFormatElement(writer, "HIGHPART",
+ rc = xmlTextWriterWriteFormatElement(writer, "HIGHPART",
"0x%"PRIX32, (u32)(time >> 32));
if (rc < 0)
return rc;
/* Writes an <IMAGE> element to the XML document. */
-static int xml_write_image_info(xmlTextWriter *writer,
+static int xml_write_image_info(xmlTextWriter *writer,
const struct image_info *image_info)
{
int rc;
if (rc < 0)
return rc;
- rc = xmlTextWriterWriteFormatAttribute(writer, "INDEX", "%"PRIu64,
+ rc = xmlTextWriterWriteFormatAttribute(writer, "INDEX", "%"PRIu64,
image_info->index);
if (rc < 0)
return rc;
- rc = xmlTextWriterWriteFormatElement(writer, "DIRCOUNT", "%"PRIu64,
+ rc = xmlTextWriterWriteFormatElement(writer, "DIRCOUNT", "%"PRIu64,
image_info->dir_count);
if (rc < 0)
return rc;
- rc = xmlTextWriterWriteFormatElement(writer, "FILECOUNT", "%"PRIu64,
+ rc = xmlTextWriterWriteFormatElement(writer, "FILECOUNT", "%"PRIu64,
image_info->file_count);
if (rc < 0)
return rc;
- rc = xmlTextWriterWriteFormatElement(writer, "TOTALBYTES", "%"PRIu64,
+ rc = xmlTextWriterWriteFormatElement(writer, "TOTALBYTES", "%"PRIu64,
image_info->total_bytes);
if (rc < 0)
return rc;
- rc = xmlTextWriterWriteFormatElement(writer, "HARDLINKBYTES", "%"PRIu64,
+ rc = xmlTextWriterWriteFormatElement(writer, "HARDLINKBYTES", "%"PRIu64,
image_info->hard_link_bytes);
if (rc < 0)
return rc;
- rc = xml_write_time(writer, "CREATIONTIME",
+ rc = xml_write_time(writer, "CREATIONTIME",
image_info->creation_time);
if (rc < 0)
return rc;
- rc = xml_write_time(writer, "LASTMODIFICATIONTIME",
+ rc = xml_write_time(writer, "LASTMODIFICATIONTIME",
image_info->last_modification_time);
if (rc < 0)
return rc;
return rc;
}
if (image_info->description) {
- rc = xmlTextWriterWriteElement(writer, "DESCRIPTION",
+ rc = xmlTextWriterWriteElement(writer, "DESCRIPTION",
image_info->description);
if (rc < 0)
return rc;
}
if (image_info->display_name) {
- rc = xmlTextWriterWriteElement(writer, "DISPLAYNAME",
+ rc = xmlTextWriterWriteElement(writer, "DISPLAYNAME",
image_info->display_name);
if (rc < 0)
return rc;
}
if (image_info->display_description) {
- rc = xmlTextWriterWriteElement(writer, "DISPLAYDESCRIPTION",
+ rc = xmlTextWriterWriteElement(writer, "DISPLAYDESCRIPTION",
image_info->display_description);
if (rc < 0)
return rc;
return &images[wim_info->num_images - 1];
}
-static int clone_windows_info(const struct windows_info *old,
+static int clone_windows_info(const struct windows_info *old,
struct windows_info *new)
{
uint i;
return WIMLIB_ERR_NOMEM;
if (old->edition_id && !(new->edition_id = STRDUP(old->edition_id)))
return WIMLIB_ERR_NOMEM;
- if (old->installation_type && !(new->installation_type =
+ if (old->installation_type && !(new->installation_type =
STRDUP(old->installation_type)))
return WIMLIB_ERR_NOMEM;
if (old->hal && !(new->hal = STRDUP(old->hal)))
return WIMLIB_ERR_NOMEM;
}
}
- if (old->default_language &&
+ if (old->default_language &&
!(new->default_language = STRDUP(old->default_language)))
return WIMLIB_ERR_NOMEM;
if (old->system_root && !(new->system_root = STRDUP(old->system_root)))
if (old->windows_info_exists) {
new->windows_info_exists = true;
- return clone_windows_info(&old->windows_info,
+ return clone_windows_info(&old->windows_info,
&new->windows_info);
}
return 0;
}
-/* Copies the XML information for an image between WIM files.
+/* Copies the XML information for an image between WIM files.
*
* @dest_image_name and @dest_image_description are ignored if they are NULL;
* otherwise, they are used to override the image name and/or image description
* On failure, WIMLIB_ERR_NOMEM is returned and no changes are made. Otherwise,
* 0 is returned and the WIM information at *new_wim_info_p is modified.
*/
-int xml_export_image(const struct wim_info *old_wim_info,
- int image,
- struct wim_info **new_wim_info_p,
- const char *dest_image_name,
+int xml_export_image(const struct wim_info *old_wim_info,
+ int image,
+ struct wim_info **new_wim_info_p,
+ const char *dest_image_name,
const char *dest_image_description)
{
struct wim_info *new_wim_info;
int i;
DEBUG("Deleting image %d from the XML data.", image);
-
+
wim_info = *wim_info_p;
wimlib_assert(wim_info);
static int calculate_dentry_statistics(struct dentry *dentry, void *arg)
{
- struct image_info *info = arg;
+ struct image_info *info = arg;
struct lookup_table *lookup_table = info->lookup_table;
const struct inode *inode = dentry->d_inode;
struct lookup_table_entry *lte;
else
info->file_count++;
- /*
+ /*
* Update total bytes and hard link bytes.
*
* Unfortunately there are some inconsistencies/bugs in the way this is
void xml_update_image_info(WIMStruct *w, int image)
{
struct image_info *image_info;
- struct dentry *root;
+ struct dentry *root;
char *flags_save;
DEBUG("Updating the image info for image %d", image);
for_dentry_in_tree(w->image_metadata[image - 1].root_dentry,
calculate_dentry_statistics,
image_info);
-
+
image_info->lookup_table = NULL;
image_info->flags = flags_save;
image_info->last_modification_time = get_wim_timestamp();
return WIMLIB_ERR_NOMEM;
}
-/* Prints information about the specified image from struct wim_info structure.
- * @image may be WIM_ALL_IMAGES. */
+/* Prints information about the specified image from struct wim_info structure.
+ * */
void print_image_info(const struct wim_info *wim_info, int image)
{
uint i;
const struct image_info *image_info;
const char *desc;
+ int start;
+ int end;
+ time_t time;
+ char *p;
+ wimlib_assert(image >= 1 && image <= wim_info->num_images);
- if (image == WIM_ALL_IMAGES) {
- for (i = 1; i <= wim_info->num_images; i++)
- print_image_info(wim_info, i);
- } else {
- time_t time;
- char *p;
+ image_info = &wim_info->images[image - 1];
- image_info = &wim_info->images[image - 1];
+ printf("Index: %"PRIu64"\n", image_info->index);
+ printf("Name: %s\n", image_info->name);
- printf("Index: %"PRIu64"\n",
- image_info->index);
- printf("Name: %s\n",
- image_info->name);
-
- /* Always print the Description: part even if there is no
- * description. */
- if (image_info->description)
- desc = image_info->description;
- else
- desc = "";
- printf("Description: %s\n", desc);
-
- if (image_info->display_name)
- printf("Display Name: %s\n",
- image_info->display_name);
-
- if (image_info->display_description)
- printf("Display Description: %s\n",
- image_info->display_description);
-
- printf("Directory Count: %"PRIu64"\n",
- image_info->dir_count);
- printf("File Count: %"PRIu64"\n",
- image_info->file_count);
- printf("Total Bytes: %"PRIu64"\n",
- image_info->total_bytes);
- printf("Hard Link Bytes: %"PRIu64"\n",
- image_info->hard_link_bytes);
-
- time = wim_timestamp_to_unix(image_info->creation_time);
- p = asctime(gmtime(&time));
- *(strrchr(p, '\n')) = '\0';
-
- printf("Creation Time: %s UTC\n", p);
-
- time = wim_timestamp_to_unix(image_info->last_modification_time);
- p = asctime(gmtime(&time));
- *(strrchr(p, '\n')) = '\0';
-
- printf("Last Modification Time: %s UTC\n", p);
- if (image_info->windows_info_exists)
- print_windows_info(&image_info->windows_info);
- if (image_info->flags)
- printf("Flags: %s\n", image_info->flags);
- putchar('\n');
- }
+ /* Always print the Description: part even if there is no
+ * description. */
+ if (image_info->description)
+ desc = image_info->description;
+ else
+ desc = "";
+ printf("Description: %s\n", desc);
+
+ if (image_info->display_name)
+ printf("Display Name: %s\n",
+ image_info->display_name);
+
+ if (image_info->display_description)
+ printf("Display Description: %s\n",
+ image_info->display_description);
+
+ printf("Directory Count: %"PRIu64"\n", image_info->dir_count);
+ printf("File Count: %"PRIu64"\n", image_info->file_count);
+ printf("Total Bytes: %"PRIu64"\n", image_info->total_bytes);
+ printf("Hard Link Bytes: %"PRIu64"\n", image_info->hard_link_bytes);
+
+ time = wim_timestamp_to_unix(image_info->creation_time);
+ p = asctime(gmtime(&time));
+ *(strrchr(p, '\n')) = '\0';
+
+ printf("Creation Time: %s UTC\n", p);
+
+ time = wim_timestamp_to_unix(image_info->last_modification_time);
+ p = asctime(gmtime(&time));
+ *(strrchr(p, '\n')) = '\0';
+
+ printf("Last Modification Time: %s UTC\n", p);
+ if (image_info->windows_info_exists)
+ print_windows_info(&image_info->windows_info);
+ if (image_info->flags)
+ printf("Flags: %s\n", image_info->flags);
+ putchar('\n');
}
-/*
+/*
* Reads the XML data from a WIM file.
*/
-int read_xml_data(FILE *fp, const struct resource_entry *res, u8 **xml_data_ret,
- struct wim_info **info_ret)
+int read_xml_data(FILE *fp, const struct resource_entry *res,
+ u8 **xml_data_ret, struct wim_info **info_ret)
{
u8 *xml_data;
xmlDoc *doc;
xmlNode *root;
int ret;
- DEBUG("XML data is %"PRIu64" bytes at offset %"PRIu64"",
+ DEBUG("XML data is %"PRIu64" bytes at offset %"PRIu64"",
(u64)res->size, res->offset);
if (resource_is_compressed(res)) {
goto err2; \
} })
-/*
+/*
* Writes XML data to a WIM file.
*
* If @total_bytes is non-zero, it specifies what to write to the TOTALBYTES
* element in the XML data. If zero, TOTALBYTES is given the default value of
* the offset of the XML data.
*/
-int write_xml_data(const struct wim_info *wim_info, int image, FILE *out,
+int write_xml_data(const struct wim_info *wim_info, int image, FILE *out,
u64 total_bytes)
{
xmlBuffer *buf;
size_t utf16_len;
size_t bytes_written;
- wimlib_assert(image == WIM_ALL_IMAGES ||
- (wim_info != NULL && image >= 1 &&
+ wimlib_assert(image == WIM_ALL_IMAGES ||
+ (wim_info != NULL && image >= 1 &&
image <= wim_info->num_images));
/* The contents of the <TOTALBYTES> element in the XML data, under the
goto err2;
}
- if ((putc(0xff, out)) == EOF || (putc(0xfe, out) == EOF) ||
+ if ((putc(0xff, out)) == EOF || (putc(0xfe, out) == EOF) ||
((bytes_written = fwrite(utf16_str, 1, utf16_len, out))
!= utf16_len)) {
ERROR_WITH_ERRNO("Error writing XML data");
}
/* Returns the description of the specified image. */
-WIMLIBAPI const char *wimlib_get_image_description(const WIMStruct *w,
+WIMLIBAPI const char *wimlib_get_image_description(const WIMStruct *w,
int image)
{
DEBUG("Getting the description of image %d", image);
WIMLIBAPI int wimlib_extract_xml_data(WIMStruct *w, FILE *fp)
{
DEBUG("Extracting the XML data.");
- if (fwrite(w->xml_data, 1, w->hdr.xml_res_entry.size, fp) !=
+ if (fwrite(w->xml_data, 1, w->hdr.xml_res_entry.size, fp) !=
w->hdr.xml_res_entry.size) {
ERROR_WITH_ERRNO("Failed to extract XML data");
return WIMLIB_ERR_WRITE;
}
/* Sets the description of an image in the WIM. */
-WIMLIBAPI int wimlib_set_image_descripton(WIMStruct *w, int image,
+WIMLIBAPI int wimlib_set_image_descripton(WIMStruct *w, int image,
const char *description)
{
char *p;