]> wimlib.net Git - wimlib/commitdiff
Split wim_resource_spec from wim_lookup_table_entry
authorEric Biggers <ebiggers3@gmail.com>
Sat, 14 Dec 2013 05:06:07 +0000 (23:06 -0600)
committerEric Biggers <ebiggers3@gmail.com>
Sat, 14 Dec 2013 05:06:07 +0000 (23:06 -0600)
26 files changed:
include/wimlib.h
include/wimlib/header.h
include/wimlib/lookup_table.h
include/wimlib/resource.h
include/wimlib/wim.h
include/wimlib/write.h
include/wimlib/xml.h
src/add_image.c
src/dentry.c
src/extract.c
src/header.c
src/integrity.c
src/lookup_table.c
src/metadata_resource.c
src/mount_image.c
src/ntfs-3g_apply.c
src/ntfs-3g_capture.c
src/reparse.c
src/resource.c
src/split.c
src/unix_apply.c
src/unix_capture.c
src/wim.c
src/win32_apply.c
src/write.c
src/xml.c

index 4e999d69caa8670031e9e95ca819d92224858dad..c777541683ccc996b3b80b3b656fbe5b342daef3 100644 (file)
@@ -425,6 +425,9 @@ enum wimlib_compression_type {
 
        /** Compressed resources in the WIM use XPRESS compression. */
        WIMLIB_COMPRESSION_TYPE_XPRESS = 2,
+
+       /** TODO  */
+       WIMLIB_COMPRESSION_TYPE_LZMS = 3,
 };
 
 /** @} */
index f7c4b7fff1818844637474a8a4c1452b818febcc..2fe76d4cad8c05eff420fb77c95a59a59f586e8b 100644 (file)
 /* Version of the WIM file.  There is an older version (used for prerelease
  * versions of Windows Vista), but wimlib doesn't support it.  The differences
  * between the versions are undocumented.  */
-#define WIM_VERSION 0x10d00
+#define WIM_VERSION_DEFAULT 0x10d00
 
 /* Version number used for a different WIM format, which as of Windows 8 can be
  * created by passing 0x20000000 in dwFlagsAndAttributes to WIMGAPI's
  * WIMCreateFile() and specifying either NONE, XPRESS, or LZMS compression.
- * This format is, however, currently undocumented by Microsoft and is seemingly
- * incompatible with their own ImageX and Dism programs.  wimlib does not yet
- * support this format.  */
-#define WIM_MYSTERY_VERSION 0xe00
+ * This format is currently undocumented by Microsoft and is seemingly
+ * incompatible with their own ImageX and Dism programs; however, it seems to be
+ * used for Windows 8 updates.  The format appears to feature a new flag (0x10)
+ * in resource entries, which I've named WIM_RESHDR_FLAG_CONCAT.  */
+#define WIM_VERSION_STREAM_CONCAT 0xe00
 
 /* WIM magic characters, translated to a single 64-bit little endian number.  */
 #define WIM_MAGIC \
@@ -57,8 +58,8 @@ struct wim_header_disk {
         * (currently the only supported value). */
        u32 hdr_size;
 
-       /* Version of the WIM file; WIM_VERSION expected (currently the only
-        * supported value). */
+       /* Version of the WIM file
+        * TODO  */
        u32 wim_version;
 
        /* Flags for the WIM file (WIM_HDR_FLAG_*) */
@@ -84,14 +85,14 @@ struct wim_header_disk {
        u32 image_count;
 
        /* Location and size of the WIM's lookup table. */
-       struct resource_entry_disk lookup_table_res_entry;
+       struct wim_reshdr_disk lookup_table_reshdr;
 
        /* Location and size of the WIM's XML data. */
-       struct resource_entry_disk xml_data_res_entry;
+       struct wim_reshdr_disk xml_data_reshdr;
 
        /* Location and size of metadata resource for the bootable image of the
         * WIM, or all zeroes if no image is bootable. */
-       struct resource_entry_disk boot_metadata_res_entry;
+       struct wim_reshdr_disk boot_metadata_reshdr;
 
        /* 1-based index of the bootable image of the WIM, or 0 if no image is
         * bootable. */
@@ -100,10 +101,10 @@ struct wim_header_disk {
        /* Location and size of the WIM's integrity table, or all zeroes if the
         * WIM has no integrity table.
         *
-        * Note the integrity_table_res_entry here is 4-byte aligned even though
+        * Note the integrity_table_reshdr here is 4-byte aligned even though
         * it would ordinarily be 8-byte aligned--- hence, the _packed_attribute
         * on the `struct wim_header_disk' is essential. */
-       struct resource_entry_disk integrity_table_res_entry;
+       struct wim_reshdr_disk integrity_table_reshdr;
 
        /* Unused bytes. */
        u8 unused[60];
@@ -118,6 +119,9 @@ struct wim_header {
        /* Magic characters: either WIM_MAGIC or PWM_MAGIC.  */
        le64 magic;
 
+       /* Version of the WIM file  */
+       u32 wim_version;
+
        /* Bitwise OR of one or more of the WIM_HDR_FLAG_* defined below. */
        u32 flags;
 
@@ -137,15 +141,15 @@ struct wim_header {
        u32 image_count;
 
        /* Location, size, and flags of the lookup table of the WIM. */
-       struct resource_entry lookup_table_res_entry;
+       struct wim_reshdr lookup_table_reshdr;
 
        /* Location, size, and flags for the XML data of the WIM. */
-       struct resource_entry xml_res_entry;
+       struct wim_reshdr xml_data_reshdr;
 
        /* Location, size, and flags for the boot metadata.  This means the
         * metadata resource for the image specified by boot_idx below.  Should
         * be zeroed out if boot_idx is 0. */
-       struct resource_entry boot_metadata_res_entry;
+       struct wim_reshdr boot_metadata_reshdr;
 
        /* The index of the bootable image in the WIM file. If 0, there are no
         * bootable images available. */
@@ -153,7 +157,7 @@ struct wim_header {
 
        /* The location of the optional integrity table used to verify the
         * integrity WIM.  Zeroed out if there is no integrity table.*/
-       struct resource_entry integrity;
+       struct wim_reshdr integrity_table_reshdr;
 };
 
 /* Flags for the `flags' field of the struct wim_header: */
index d1b980dafe240f4ae18c33c05443ed9f09c98b9f..b5b3830fcbde38ac13ee876aaec39ccf23aaf753 100644 (file)
@@ -114,24 +114,11 @@ struct wim_lookup_table_entry {
        /* List of lookup table entries in this hash bucket */
        struct hlist_node hash_list;
 
-       /* Location and size of the stream in the WIM, whether it is compressed
-        * or not, and whether it's a metadata resource or not.  This is an
-        * on-disk field. */
-       struct resource_entry resource_entry;
+       /* Uncompressed size of the stream.  */
+       u64 size : 56;
 
-       /* Specifies which part of the split WIM the resource is located in.
-        * This is on on-disk field.
-        *
-        * In stand-alone WIMs, this must be 1.
-        *
-        * In split WIMs, every split WIM part has its own lookup table, and in
-        * read_lookup_table() it's currently expected that the part number of
-        * each lookup table entry in a split WIM part's lookup table is the
-        * same as the part number of that split WIM part.  So this makes this
-        * field redundant since we store a pointer to the corresponding
-        * WIMStruct in the lookup table entry anyway.
-        */
-       u16 part_number;
+       /* Stream flags (WIM_RESHDR_FLAG_*).  */
+       u64 flags : 8;
 
        /* One of the `enum resource_location' values documented above. */
        u16 resource_location : 5;
@@ -147,17 +134,6 @@ struct wim_lookup_table_entry {
 
        u16 no_progress : 1;
 
-       /* If resource_location == RESOURCE_IN_WIM, this will be a cached value
-        * that specifies the compression type of this stream as one of
-        * WIMLIB_COMPRESSION_TYPE_*.  Otherwise this will be 0, which is the
-        * same as WIMLIB_COMPRESSION_TYPE_NONE.  */
-       u16 compression_type : 2;
-
-       /* If resource_location == RESOURCE_IN_WIM, this flag will be set if the
-        * WIM is pipable and therefore the stream is in a slightly different
-        * format.  See comment above write_pipable_wim().  */
-       u16 is_pipable : 1;
-
        /* Set to 1 when a metadata entry has its checksum changed; in such
         * cases the hash is no longer valid to verify the data if the metadata
         * resource is read again.  */
@@ -209,7 +185,7 @@ struct wim_lookup_table_entry {
        /* Pointers to somewhere where the stream is actually located.  See the
         * comments for the @resource_location field above. */
        union {
-               WIMStruct *wim;
+               struct wim_resource_spec *rspec;
                tchar *file_on_disk;
                void *attached_buffer;
        #ifdef WITH_FUSE
@@ -254,15 +230,9 @@ struct wim_lookup_table_entry {
                        struct list_head being_compressed_list;
                };
 
-               /* When a WIM file is written, @output_resource_entry is filled
-                * in with the resource entry for the output WIM.  This will not
-                * necessarily be the same as the @resource_entry since:
-                * - The stream may have a different offset in the new WIM
-                * - The stream may have a different compressed size in the new
-                *   WIM if the compression type changed
-                */
-               struct resource_entry output_resource_entry;
-
+               /* When a WIM file is written, @output_reshdr is filled in with
+                * the resource header for the output WIM.  */
+               struct wim_reshdr out_reshdr;
 
                /* Used temporarily during extraction  */
                union {
@@ -290,37 +260,29 @@ struct wim_lookup_table_entry {
        /* Links streams that are still unhashed after being been added
         * to a WIM.  */
        struct list_head unhashed_list;
+
+       struct list_head wim_resource_list;
 };
 
-static inline u64
-wim_resource_size(const struct wim_lookup_table_entry *lte)
+static inline int
+lte_ctype(const struct wim_lookup_table_entry *lte)
 {
-       return lte->resource_entry.original_size;
+       if (lte->resource_location == RESOURCE_IN_WIM)
+               return lte->rspec->ctype;
+       else
+               return WIMLIB_COMPRESSION_TYPE_NONE;
 }
 
 static inline u32
-wim_resource_chunk_size(const struct wim_lookup_table_entry * lte)
+lte_cchunk_size(const struct wim_lookup_table_entry * lte)
 {
        if (lte->resource_location == RESOURCE_IN_WIM &&
-           lte->compression_type != WIMLIB_COMPRESSION_TYPE_NONE)
-               return lte->wim->chunk_size;
+           lte->rspec->ctype != WIMLIB_COMPRESSION_TYPE_NONE)
+               return lte->rspec->cchunk_size;
        else
                return 32768;
 }
 
-
-static inline u64
-wim_resource_chunks(const struct wim_lookup_table_entry *lte)
-{
-       return DIV_ROUND_UP(wim_resource_size(lte), wim_resource_chunk_size(lte));
-}
-
-static inline int
-wim_resource_compression_type(const struct wim_lookup_table_entry *lte)
-{
-       return lte->compression_type;
-}
-
 static inline bool
 lte_filename_valid(const struct wim_lookup_table_entry *lte)
 {
@@ -342,7 +304,7 @@ read_wim_lookup_table(WIMStruct *wim);
 
 extern int
 write_wim_lookup_table(WIMStruct *wim, int image, int write_flags,
-                      struct resource_entry *out_res_entry,
+                      struct wim_reshdr *out_reshdr,
                       struct list_head *stream_list_override);
 
 extern void
@@ -369,8 +331,7 @@ clone_lookup_table_entry(const struct wim_lookup_table_entry *lte)
                        _malloc_attribute;
 
 extern void
-print_lookup_table_entry(const struct wim_lookup_table_entry *entry,
-                        FILE *out);
+print_lookup_table_entry(const struct wim_lookup_table_entry *lte, FILE *out);
 
 extern void
 free_lookup_table_entry(struct wim_lookup_table_entry *lte);
@@ -413,16 +374,32 @@ lte_decrement_num_opened_fds(struct wim_lookup_table_entry *lte);
 #endif
 
 extern int
-lte_zero_out_refcnt(struct wim_lookup_table_entry *entry, void *ignore);
+lte_zero_out_refcnt(struct wim_lookup_table_entry *lte, void *ignore);
 
 extern int
-lte_zero_real_refcnt(struct wim_lookup_table_entry *entry, void *ignore);
+lte_zero_real_refcnt(struct wim_lookup_table_entry *lte, void *ignore);
 
 extern int
 lte_free_extracted_file(struct wim_lookup_table_entry *lte, void *ignore);
 
-extern void
-lte_init_wim(struct wim_lookup_table_entry *lte, WIMStruct *wim);
+static inline void
+lte_bind_wim_resource_spec(struct wim_lookup_table_entry *lte,
+                          struct wim_resource_spec *rspec)
+{
+       lte->resource_location = RESOURCE_IN_WIM;
+       lte->rspec = rspec;
+       list_add(&lte->wim_resource_list, &rspec->lte_list);
+       lte->flags = rspec->flags;
+       lte->size = rspec->uncompressed_size;
+}
+
+static inline void
+lte_unbind_wim_resource_spec(struct wim_lookup_table_entry *lte)
+{
+       list_del(&lte->wim_resource_list);
+       lte->rspec = NULL;
+       lte->resource_location = RESOURCE_NONEXISTENT;
+}
 
 extern int
 inode_resolve_ltes(struct wim_inode *inode, struct wim_lookup_table *table,
@@ -530,10 +507,6 @@ inode_unnamed_lte(const struct wim_inode *inode, const struct wim_lookup_table *
 extern const u8 *
 inode_unnamed_stream_hash(const struct wim_inode *inode);
 
-extern u64
-lookup_table_total_stream_size(struct wim_lookup_table *table);
-
-
 static inline void
 lookup_table_insert_unhashed(struct wim_lookup_table *table,
                             struct wim_lookup_table_entry *lte,
index 9bb6749071eb2687581e5ff1f07a9101f0a0d565..a717e4945ccf084e6077f34b1f99801c1a793755 100644 (file)
@@ -5,43 +5,85 @@
 #include "wimlib/endianness.h"
 #include "wimlib/callback.h"
 #include "wimlib/file_io.h"
+#include "wimlib/list.h"
 #include "wimlib/sha1.h"
 
 struct wim_lookup_table_entry;
 struct wim_image_metadata;
 
-/* Description of the location, size, and compression status of a WIM resource
- * (stream).  This is the in-memory version of `struct resource_entry_disk'.  */
-struct resource_entry {
-       /* Size, in bytes, of the resource as it appears in the WIM file.  If
-        * the resource is uncompressed, this will be the same as
-        * @original_size.  If the resource is compressed, this will be the
-        * compressed size of the resource, including all compressed chunks as
-        * well as the chunk table.
-        *
-        * Note: if the WIM is "pipable", this value does not include the stream
-        * header.  */
-       u64 size  : 56;
-
-       /* Bitwise OR of one or more of the WIM_RESHDR_FLAG_* flags.  */
-       u64 flags : 8;
+/* Specification of a resource in a WIM file.
+ *
+ * If a `struct wim_lookup_table_entry' lte has
+ * (lte->resource_location == RESOURCE_IN_WIM), then lte->wim_res_spec points to
+ * an instance of this structure.
+ *
+ * Normally, there is a one-to-one correspondence between WIM lookup table
+ * entries ("streams") and WIM resources.  However, the flag
+ * WIM_RESHDR_FLAG_CONCAT can be used to specify that two streams be combined
+ * into the same resource and compressed together.  Caveats about this flag are
+ * noted in the comment above the definition of WIM_VERSION_STREAM_CONCAT.  */
+struct wim_resource_spec {
+       /* The WIM file containing this resource.  */
+       WIMStruct *wim;
+
+       /* Offset, in bytes, from the start of WIM file at which this resource
+        * starts.  */
+       u64 offset_in_wim;
+
+       /* The size of this resource in the WIM file.  For compressed resources
+        * this is the compressed size.  */
+       u64 size_in_wim;
+
+       /* Number of bytes of uncompressed data this resource uncompresses to.
+        */
+       u64 uncompressed_size;
+
+       /* List of streams this resource contains.  */
+       struct list_head lte_list;
+
+       /* Resource flags.  */
+       u32 flags : 8;
+
+       /* This flag will be set if the WIM is pipable and therefore the
+        * resource will be in a slightly different format if it is compressed
+        * (wimlib extension).  */
+       u32 is_pipable : 1;
+
+       /* Compression type of this resource as one of WIMLIB_COMPRESSION_TYPE_*
+        * constants.  */
+       u32 ctype : 3;
+
+       /* Compression chunk size.  */
+       u32 cchunk_size;
+};
 
-       /* Offset, in bytes, of the resource from the start of the WIM file.  */
-       u64 offset;
 
-       /* Uncompressed size, in bytes, of the resource (stream).  */
-       u64 original_size;
-};
+/* On-disk version of a WIM resource header:  This structure specifies the
+ * location, size, and flags (e.g. compressed or not compressed) for a resource
+ * in the WIM file.  */
+struct wim_reshdr_disk {
+       /* Size of the resource as it appears in the WIM file (possibly
+        * compressed).  */
+       u8 size_in_wim[7];
 
-/* On-disk version of `struct resource_entry'.  See `struct resource_entry' for
- * description of fields.  */
-struct resource_entry_disk {
-       u8 size[7];
+       /* WIM_RESHDR_FLAG_* flags.  */
        u8 flags;
-       le64 offset;
-       le64 original_size;
+
+       /* Offset of the resource from the start of the WIM file.  */
+       le64 offset_in_wim;
+
+       /* Uncompressed size of the resource.  */
+       le64 uncompressed_size;
 } _packed_attribute;
 
+/* In-memory version of wim_reshdr_disk.  */
+struct wim_reshdr {
+       u64 size_in_wim : 56;
+       u64 flags : 8;
+       u64 offset_in_wim;
+       u64 uncompressed_size;
+};
+
 /* Flags for the `flags' field of the struct resource_entry structure. */
 
 /* I haven't seen this flag used in any of the WIMs I have examined.  I assume
@@ -65,34 +107,37 @@ struct resource_entry_disk {
  * Either way, wimlib doesn't actually use this flag for anything.  */
 #define WIM_RESHDR_FLAG_SPANNED         0x08
 
-/* Functions that operate directly on `struct resource_entry's.  */
-
-static inline int
-resource_is_compressed(const struct resource_entry *entry)
-{
-       return (entry->flags & WIM_RESHDR_FLAG_COMPRESSED);
-}
+/* TODO  */
+#define WIM_RESHDR_FLAG_CONCAT         0x10
 
 static inline void
-copy_resource_entry(struct resource_entry *dst,
-                   const struct resource_entry *src)
+copy_reshdr(struct wim_reshdr *dest, const struct wim_reshdr *src)
 {
-       memcpy(dst, src, sizeof(struct resource_entry));
+       memcpy(dest, src, sizeof(struct wim_reshdr));
 }
 
 static inline void
-zero_resource_entry(struct resource_entry *entry)
+zero_reshdr(struct wim_reshdr *reshdr)
 {
-       memset(entry, 0, sizeof(struct resource_entry));
+       memset(reshdr, 0, sizeof(struct wim_reshdr));
 }
 
+
+extern void
+wim_res_hdr_to_spec(const struct wim_reshdr *reshdr, WIMStruct *wim,
+                   struct wim_resource_spec *rspec);
+
 extern void
-get_resource_entry(const struct resource_entry_disk *disk_entry,
-                  struct resource_entry *entry);
+wim_res_spec_to_hdr(const struct wim_resource_spec *rspec,
+                   struct wim_reshdr *reshdr);
 
 extern void
-put_resource_entry(const struct resource_entry *entry,
-                  struct resource_entry_disk *disk_entry);
+get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr,
+              struct wim_reshdr *reshdr);
+
+void
+put_wim_reshdr(const struct wim_reshdr *reshdr,
+              struct wim_reshdr_disk *disk_reshdr);
 
 /* wimlib internal flags used when reading or writing resources.  */
 #define WIMLIB_WRITE_RESOURCE_FLAG_RECOMPRESS          0x00000001
@@ -125,25 +170,14 @@ read_full_resource_into_alloc_buf(const struct wim_lookup_table_entry *lte,
                                  void **buf_ret);
 
 extern int
-res_entry_to_data(const struct resource_entry *res_entry,
-                 WIMStruct *wim, void **buf_ret);
+wim_reshdr_to_data(const struct wim_reshdr *reshdr,
+                  WIMStruct *wim, void **buf_ret);
 
 extern int
 read_resource_prefix(const struct wim_lookup_table_entry *lte,
                     u64 size, consume_data_callback_t cb,
                     u32 in_chunk_size, void *ctx_or_buf, int flags);
 
-/* Functions to write a resource.  */
-
-extern int
-write_wim_resource_from_buffer(const void *buf, size_t buf_size,
-                              int reshdr_flags, struct filedes *out_fd,
-                              int out_ctype,
-                              u32 out_chunk_size,
-                              struct resource_entry *out_res_entry,
-                              u8 *hash_ret, int write_resource_flags,
-                              struct wimlib_lzx_context **comp_ctx);
-
 /* Functions to extract a resource.  */
 
 extern int
index 4afa60eb8594943ecc8ad06e4d8912384e51627b..83b1dbcb359e3587ccfc1ef0cbfde3133a5fff1e 100644 (file)
@@ -94,7 +94,7 @@ static inline bool wim_is_pipable(const WIMStruct *wim)
 
 static inline bool wim_has_integrity_table(const WIMStruct *wim)
 {
-       return (wim->hdr.integrity.offset != 0);
+       return (wim->hdr.integrity_table_reshdr.offset_in_wim != 0);
 }
 
 static inline bool wim_has_metadata(const WIMStruct *wim)
@@ -112,8 +112,7 @@ extern int
 init_wim_header(struct wim_header *hdr, int ctype, u32 chunk_size);
 
 extern int
-read_wim_header(const tchar *filename, struct filedes *in_fd,
-               struct wim_header *hdr);
+read_wim_header(WIMStruct *wim, struct wim_header *hdr);
 
 extern int
 write_wim_header(const struct wim_header *hdr, struct filedes *out_fd);
index eb73bed3ef1fa272694140fc295ade97a85f24a5..1240c89f35b96f00e4d8470ad7b6d3a53821e24a 100644 (file)
@@ -40,4 +40,13 @@ write_wim_part(WIMStruct *wim,
               struct list_head *stream_list_override,
               const u8 *guid);
 
+int
+write_wim_resource_from_buffer(const void *buf, size_t buf_size,
+                              int reshdr_flags, struct filedes *out_fd,
+                              int out_ctype,
+                              u32 out_chunk_size,
+                              struct wim_reshdr *out_reshdr,
+                              u8 *hash_ret, int write_resource_flags,
+                              struct wimlib_lzx_context **comp_ctx);
+
 #endif /* _WIMLIB_WRITE_H */
index 0d09bf64dcf9c9abff406c9678a289c416bb7d8c..a4fd115247d391992cc121c7235e266d23222420 100644 (file)
@@ -5,7 +5,7 @@
 #include "wimlib/file_io.h"
 
 struct wim_info;
-struct resource_entry;
+struct wim_reshdr;
 
 extern u64
 wim_info_get_total_bytes(const struct wim_info *info);
@@ -51,7 +51,7 @@ read_wim_xml_data(WIMStruct *wim);
 
 extern int
 write_wim_xml_data(WIMStruct *wim, int image,
-                  u64 total_bytes, struct resource_entry *out_res_entry,
+                  u64 total_bytes, struct wim_reshdr *out_reshdr,
                   int write_resource_flags);
 
 extern void
index 746c06a92dd43ed6d1cf0c427b5e1080988699ec..a06ee939cbb9b68c44ad4d3d40ed08231022220c 100644 (file)
@@ -45,14 +45,14 @@ add_new_dentry_tree(WIMStruct *wim, struct wim_dentry *root_dentry,
        int ret;
 
        metadata_lte = new_lookup_table_entry();
-       if (!metadata_lte)
+       if (metadata_lte == NULL)
                return WIMLIB_ERR_NOMEM;
 
-       metadata_lte->resource_entry.flags = WIM_RESHDR_FLAG_METADATA;
+       metadata_lte->flags = WIM_RESHDR_FLAG_METADATA;
        metadata_lte->unhashed = 1;
 
        new_imd = new_image_metadata();
-       if (!new_imd) {
+       if (new_imd == NULL) {
                free_lookup_table_entry(metadata_lte);
                return WIMLIB_ERR_NOMEM;
        }
@@ -92,7 +92,7 @@ wimlib_add_empty_image(WIMStruct *wim, const tchar *name, int *new_idx_ret)
        }
 
        sd = new_wim_security_data();
-       if (!sd) {
+       if (sd == NULL) {
                ret = WIMLIB_ERR_NOMEM;
                goto out;
        }
@@ -172,7 +172,7 @@ wimlib_add_image_multisource(WIMStruct *wim,
        /* Translate the "capture sources" into generic update commands. */
        add_cmds = capture_sources_to_add_cmds(sources, num_sources,
                                               add_flags, config);
-       if (!add_cmds) {
+       if (add_cmds == NULL) {
                ret = WIMLIB_ERR_NOMEM;
                goto out_delete_image;
        }
index b2bddf2293f14f20e24280f0bb66de823d6e352a..37405eb027316af95a8661cb6a99e1d57fe5408a 100644 (file)
@@ -254,7 +254,7 @@ get_utf16le_name(const tchar *name, utf16lechar **name_utf16le_ret,
 #if TCHAR_IS_UTF16LE
        name_utf16le_nbytes = tstrlen(name) * sizeof(utf16lechar);
        name_utf16le = MALLOC(name_utf16le_nbytes + sizeof(utf16lechar));
-       if (!name_utf16le)
+       if (name_utf16le == NULL)
                return WIMLIB_ERR_NOMEM;
        memcpy(name_utf16le, name, name_utf16le_nbytes + sizeof(utf16lechar));
        ret = 0;
@@ -443,7 +443,7 @@ for_dentry_in_tree(struct wim_dentry *root,
 {
        int ret;
 
-       if (!root)
+       if (root == NULL)
                return 0;
        ret = (*visitor)(root, arg);
        if (ret)
@@ -461,7 +461,7 @@ for_dentry_in_tree_depth(struct wim_dentry *root,
 {
        int ret;
 
-       if (!root)
+       if (root == NULL)
                return 0;
        ret = for_dentry_tree_in_rbtree_depth(root->d_inode->i_children.rb_node,
                                              visitor, arg);
@@ -485,7 +485,7 @@ calculate_dentry_full_path(struct wim_dentry *dentry)
        if (dentry_is_root(dentry)) {
                static const tchar _root_path[] = {WIM_PATH_SEPARATOR, T('\0')};
                full_path = TSTRDUP(_root_path);
-               if (!full_path)
+               if (full_path == NULL)
                        return WIMLIB_ERR_NOMEM;
                full_path_nbytes = 1 * sizeof(tchar);
        } else {
@@ -499,7 +499,7 @@ calculate_dentry_full_path(struct wim_dentry *dentry)
                        parent_full_path = T("");
                        parent_full_path_nbytes = 0;
                } else {
-                       if (!parent->_full_path) {
+                       if (parent->_full_path == NULL) {
                                ret = calculate_dentry_full_path(parent);
                                if (ret)
                                        return ret;
@@ -525,7 +525,7 @@ calculate_dentry_full_path(struct wim_dentry *dentry)
                full_path_nbytes = parent_full_path_nbytes + sizeof(tchar) +
                                   filename_nbytes;
                full_path = MALLOC(full_path_nbytes + sizeof(tchar));
-               if (!full_path)
+               if (full_path == NULL)
                        return WIMLIB_ERR_NOMEM;
                memcpy(full_path, parent_full_path, parent_full_path_nbytes);
                full_path[parent_full_path_nbytes / sizeof(tchar)] = WIM_PATH_SEPARATOR;
@@ -790,7 +790,7 @@ get_dentry_utf16le(WIMStruct *wim, const utf16lechar *path)
        const utf16lechar *p, *pp;
 
        cur_dentry = parent_dentry = wim_root_dentry(wim);
-       if (!cur_dentry) {
+       if (cur_dentry == NULL) {
                errno = ENOENT;
                return NULL;
        }
@@ -1045,7 +1045,7 @@ new_dentry(const tchar *name, struct wim_dentry **dentry_ret)
        int ret;
 
        dentry = MALLOC(sizeof(struct wim_dentry));
-       if (!dentry)
+       if (dentry == NULL)
                return WIMLIB_ERR_NOMEM;
 
        dentry_common_init(dentry);
@@ -1077,7 +1077,7 @@ _new_dentry_with_inode(const tchar *name, struct wim_dentry **dentry_ret,
                dentry->d_inode = new_timeless_inode();
        else
                dentry->d_inode = new_inode();
-       if (!dentry->d_inode) {
+       if (dentry->d_inode == NULL) {
                free_dentry(dentry);
                return WIMLIB_ERR_NOMEM;
        }
@@ -1139,7 +1139,7 @@ init_ads_entry(struct wim_ads_entry *ads_entry, const void *name,
 
        if (is_utf16le) {
                utf16lechar *p = MALLOC(name_nbytes + sizeof(utf16lechar));
-               if (!p)
+               if (p == NULL)
                        return WIMLIB_ERR_NOMEM;
                memcpy(p, name, name_nbytes);
                p[name_nbytes / 2] = cpu_to_le16(0);
@@ -1455,7 +1455,7 @@ do_inode_add_ads(struct wim_inode *inode, const void *stream_name,
        num_ads = inode->i_num_ads + 1;
        ads_entries = REALLOC(inode->i_ads_entries,
                              num_ads * sizeof(inode->i_ads_entries[0]));
-       if (!ads_entries) {
+       if (ads_entries == NULL) {
                ERROR("Failed to allocate memory for new alternate data stream");
                return NULL;
        }
@@ -1503,22 +1503,22 @@ add_stream_from_data_buffer(const void *buffer, size_t size,
        sha1_buffer(buffer, size, hash);
        existing_lte = lookup_resource(lookup_table, hash);
        if (existing_lte) {
-               wimlib_assert(wim_resource_size(existing_lte) == size);
+               wimlib_assert(existing_lte->size == size);
                lte = existing_lte;
                lte->refcnt++;
        } else {
                void *buffer_copy;
                lte = new_lookup_table_entry();
-               if (!lte)
+               if (lte == NULL)
                        return NULL;
                buffer_copy = memdup(buffer, size);
-               if (!buffer_copy) {
+               if (buffer_copy == NULL) {
                        free_lookup_table_entry(lte);
                        return NULL;
                }
-               lte->resource_location            = RESOURCE_IN_ATTACHED_BUFFER;
-               lte->attached_buffer              = buffer_copy;
-               lte->resource_entry.original_size = size;
+               lte->resource_location  = RESOURCE_IN_ATTACHED_BUFFER;
+               lte->attached_buffer    = buffer_copy;
+               lte->size               = size;
                copy_hash(lte->hash, hash);
                lookup_table_insert(lookup_table, lte);
        }
@@ -1535,12 +1535,12 @@ inode_add_ads_with_data(struct wim_inode *inode, const tchar *name,
        wimlib_assert(inode->i_resolved);
 
        new_ads_entry = inode_add_ads(inode, name);
-       if (!new_ads_entry)
+       if (new_ads_entry == NULL)
                return WIMLIB_ERR_NOMEM;
 
        new_ads_entry->lte = add_stream_from_data_buffer(value, size,
                                                         lookup_table);
-       if (!new_ads_entry->lte) {
+       if (new_ads_entry->lte == NULL) {
                inode_remove_ads(inode, new_ads_entry - inode->i_ads_entries,
                                 lookup_table);
                return WIMLIB_ERR_NOMEM;
@@ -1564,7 +1564,7 @@ inode_set_unnamed_stream(struct wim_inode *inode, const void *data, size_t len,
                         struct wim_lookup_table *lookup_table)
 {
        inode->i_lte = add_stream_from_data_buffer(data, len, lookup_table);
-       if (!inode->i_lte)
+       if (inode->i_lte == NULL)
                return WIMLIB_ERR_NOMEM;
        inode->i_resolved = 1;
        return 0;
@@ -1621,17 +1621,17 @@ inode_get_unix_data(const struct wim_inode *inode,
 
        ads_entry = inode_get_ads_entry((struct wim_inode*)inode,
                                        WIMLIB_UNIX_DATA_TAG, NULL);
-       if (!ads_entry)
+       if (ads_entry == NULL)
                return NO_UNIX_DATA;
 
        if (stream_idx_ret)
                *stream_idx_ret = ads_entry - inode->i_ads_entries;
 
        lte = ads_entry->lte;
-       if (!lte)
+       if (lte == NULL)
                return NO_UNIX_DATA;
 
-       size = wim_resource_size(lte);
+       size = lte->size;
        if (size != sizeof(struct wimlib_unix_data))
                return BAD_UNIX_DATA;
 
@@ -1714,7 +1714,7 @@ read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode,
         * data stream entries. */
        num_ads = inode->i_num_ads;
        ads_entries = CALLOC(num_ads, sizeof(inode->i_ads_entries[0]));
-       if (!ads_entries)
+       if (ads_entries == NULL)
                goto out_of_memory;
 
        /* Read the entries into our newly allocated buffer. */
@@ -1769,7 +1769,7 @@ read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode,
                                goto out_invalid;
 
                        cur_entry->stream_name = MALLOC(cur_entry->stream_name_nbytes + 2);
-                       if (!cur_entry->stream_name)
+                       if (cur_entry->stream_name == NULL)
                                goto out_of_memory;
 
                        memcpy(cur_entry->stream_name,
@@ -1908,7 +1908,7 @@ read_dentry(const u8 * restrict metadata_resource, u64 metadata_resource_len,
 
        /* Allocate a `struct wim_inode' for this `struct wim_dentry'. */
        inode = new_timeless_inode();
-       if (!inode)
+       if (inode == NULL)
                return WIMLIB_ERR_NOMEM;
 
        /* Read more fields; some into the dentry, and some into the inode. */
@@ -1976,7 +1976,7 @@ read_dentry(const u8 * restrict metadata_resource, u64 metadata_resource_len,
         * is no null terminator following it. */
        if (file_name_nbytes) {
                file_name = MALLOC(file_name_nbytes + 2);
-               if (!file_name) {
+               if (file_name == NULL) {
                        ERROR("Failed to allocate %d bytes for dentry file name",
                              file_name_nbytes + 2);
                        ret = WIMLIB_ERR_NOMEM;
@@ -1994,7 +1994,7 @@ read_dentry(const u8 * restrict metadata_resource, u64 metadata_resource_len,
         * filename, there is no null terminator following it. */
        if (short_name_nbytes) {
                short_name = MALLOC(short_name_nbytes + 2);
-               if (!short_name) {
+               if (short_name == NULL) {
                        ERROR("Failed to allocate %d bytes for dentry short name",
                              short_name_nbytes + 2);
                        ret = WIMLIB_ERR_NOMEM;
@@ -2131,7 +2131,7 @@ read_dentry_tree(const u8 * restrict metadata_resource,
                /* Not end of directory.  Allocate this child permanently and
                 * link it to the parent and previous child. */
                child = memdup(&cur_child, sizeof(struct wim_dentry));
-               if (!child) {
+               if (child == NULL) {
                        ERROR("Failed to allocate new dentry!");
                        ret = WIMLIB_ERR_NOMEM;
                        break;
@@ -2523,7 +2523,7 @@ do_iterate_dir_tree(WIMStruct *wim,
        wdentry = CALLOC(1, sizeof(struct wimlib_dir_entry) +
                                  (1 + dentry->d_inode->i_num_ads) *
                                        sizeof(struct wimlib_stream_entry));
-       if (!wdentry)
+       if (wdentry == NULL)
                goto out;
 
        ret = init_wimlib_dentry(wdentry, dentry, wim, flags);
@@ -2568,7 +2568,7 @@ image_do_iterate_dir_tree(WIMStruct *wim)
        struct wim_dentry *dentry;
 
        dentry = get_dentry(wim, ctx->path);
-       if (!dentry)
+       if (dentry == NULL)
                return WIMLIB_ERR_PATH_DOES_NOT_EXIST;
        return do_iterate_dir_tree(wim, dentry, ctx->flags, ctx->cb, ctx->user_ctx);
 }
@@ -2626,7 +2626,7 @@ inode_metadata_consistent(const struct wim_inode *inode,
 
                /* Compare stream sizes.  */
                if (lte && template_lte) {
-                       if (wim_resource_size(lte) != wim_resource_size(template_lte))
+                       if (lte->size != template_lte->size)
                                return false;
 
                        /* If hash happens to be available, compare with template.  */
@@ -2634,9 +2634,9 @@ inode_metadata_consistent(const struct wim_inode *inode,
                            !hashes_equal(lte->hash, template_lte->hash))
                                return false;
 
-               } else if (lte && wim_resource_size(lte)) {
+               } else if (lte && lte->size) {
                        return false;
-               } else if (template_lte && wim_resource_size(template_lte)) {
+               } else if (template_lte && template_lte->size) {
                        return false;
                }
        }
@@ -2673,7 +2673,7 @@ inode_copy_checksums(struct wim_inode *inode,
                /* Only take action if both entries exist, the entry for @inode
                 * has no checksum calculated, but the entry for @template_inode
                 * does.  */
-               if (!lte || !template_lte ||
+               if (lte == NULL || template_lte == NULL ||
                    !lte->unhashed || template_lte->unhashed)
                        continue;
 
@@ -2736,7 +2736,7 @@ dentry_reference_template(struct wim_dentry *dentry, void *_args)
                return ret;
 
        template_dentry = get_dentry(template_wim, dentry->_full_path);
-       if (!template_dentry) {
+       if (template_dentry == NULL) {
                DEBUG("\"%"TS"\": newly added file", dentry->_full_path);
                return 0;
        }
index 4448a6ea271722200d74bab3d018661c9868c7d5..549c92f7d1ec7b0df10e967609d26db31a2fc125 100644 (file)
@@ -129,7 +129,7 @@ ref_stream_to_extract(struct wim_lookup_table_entry *lte,
            (!is_linked_extraction(ctx) || (lte->out_refcnt == 0 &&
                                            lte->extracted_file == NULL)))
        {
-               ctx->progress.extract.total_bytes += wim_resource_size(lte);
+               ctx->progress.extract.total_bytes += lte->size;
                ctx->progress.extract.num_streams++;
        }
 
@@ -237,7 +237,7 @@ update_extract_progress(struct apply_ctx *ctx,
        wimlib_progress_func_t progress_func = ctx->progress_func;
        union wimlib_progress_info *progress = &ctx->progress;
 
-       progress->extract.completed_bytes += wim_resource_size(lte);
+       progress->extract.completed_bytes += lte->size;
        if (progress_func &&
            progress->extract.completed_bytes >= ctx->next_progress)
        {
@@ -1257,8 +1257,7 @@ extract_stream_instances(struct wim_lookup_table_entry *lte,
                        goto out_free_lte_tmp;
                }
                filedes_init(&fd, raw_fd);
-               ret = extract_wim_resource_to_fd(lte, &fd,
-                                                wim_resource_size(lte));
+               ret = extract_wim_resource_to_fd(lte, &fd, lte->size);
                if (filedes_close(&fd) && !ret)
                        ret = WIMLIB_ERR_WRITE;
                if (ret)
@@ -1327,12 +1326,14 @@ extract_stream_list(struct apply_ctx *ctx)
 /* Read the header from a stream in a pipable WIM.  */
 static int
 read_pwm_stream_header(WIMStruct *pwm, struct wim_lookup_table_entry *lte,
+                      struct wim_resource_spec *rspec,
                       int flags, struct wim_header_disk *hdr_ret)
 {
        union {
                struct pwm_stream_hdr stream_hdr;
                struct wim_header_disk pwm_hdr;
        } buf;
+       struct wim_reshdr reshdr;
        int ret;
 
        ret = full_read(&pwm->in_fd, &buf.stream_hdr, sizeof(buf.stream_hdr));
@@ -1356,20 +1357,14 @@ read_pwm_stream_header(WIMStruct *pwm, struct wim_lookup_table_entry *lte,
                return WIMLIB_ERR_INVALID_PIPABLE_WIM;
        }
 
-       lte->resource_entry.original_size = le64_to_cpu(buf.stream_hdr.uncompressed_size);
        copy_hash(lte->hash, buf.stream_hdr.hash);
-       lte->resource_entry.flags = le32_to_cpu(buf.stream_hdr.flags);
-       lte->resource_entry.offset = pwm->in_fd.offset;
-       lte->resource_location = RESOURCE_IN_WIM;
-       lte->wim = pwm;
-       if (lte->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED) {
-               lte->compression_type = pwm->compression_type;
-               lte->resource_entry.size = 0;
-       } else {
-               lte->compression_type = WIMLIB_COMPRESSION_TYPE_NONE;
-               lte->resource_entry.size = lte->resource_entry.original_size;
-       }
-       lte->is_pipable = 1;
+
+       reshdr.size_in_wim = 0;
+       reshdr.flags = le32_to_cpu(buf.stream_hdr.flags);
+       reshdr.offset_in_wim = pwm->in_fd.offset;
+       reshdr.uncompressed_size = le64_to_cpu(buf.stream_hdr.uncompressed_size);
+       wim_res_hdr_to_spec(&reshdr, pwm, rspec);
+       lte_bind_wim_resource_spec(lte, rspec);
        return 0;
 
 read_error:
@@ -1389,9 +1384,9 @@ static int
 skip_pwm_stream(struct wim_lookup_table_entry *lte)
 {
        return read_partial_wim_resource(lte,
-                                        wim_resource_size(lte),
+                                        lte->size,
                                         skip_pwm_chunk_cb,
-                                        wim_resource_chunk_size(lte),
+                                        lte_cchunk_size(lte),
                                         NULL,
                                         WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS,
                                         0);
@@ -1401,6 +1396,7 @@ static int
 extract_streams_from_pipe(struct apply_ctx *ctx)
 {
        struct wim_lookup_table_entry *found_lte;
+       struct wim_resource_spec *rspec;
        struct wim_lookup_table_entry *needed_lte;
        struct wim_lookup_table *lookup_table;
        struct wim_header_disk pwm_hdr;
@@ -1409,9 +1405,13 @@ extract_streams_from_pipe(struct apply_ctx *ctx)
 
        ret = WIMLIB_ERR_NOMEM;
        found_lte = new_lookup_table_entry();
-       if (!found_lte)
+       if (found_lte == NULL)
                goto out;
 
+       rspec = MALLOC(sizeof(struct wim_resource_spec));
+       if (rspec == NULL)
+               goto out_free_found_lte;
+
        lookup_table = ctx->wim->lookup_table;
        pwm_flags = PWM_ALLOW_WIM_HDR;
        if ((ctx->extract_flags & WIMLIB_EXTRACT_FLAG_RESUME))
@@ -1423,8 +1423,10 @@ extract_streams_from_pipe(struct apply_ctx *ctx)
                ctx->progress_func(WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN,
                                   &ctx->progress);
        while (ctx->num_streams_remaining) {
-               ret = read_pwm_stream_header(ctx->wim, found_lte, pwm_flags,
-                                            &pwm_hdr);
+               if (found_lte->resource_location != RESOURCE_NONEXISTENT)
+                       lte_unbind_wim_resource_spec(found_lte);
+               ret = read_pwm_stream_header(ctx->wim, found_lte, rspec,
+                                            pwm_flags, &pwm_hdr);
                if (ret) {
                        if (ret == WIMLIB_ERR_UNEXPECTED_END_OF_FILE &&
                            (ctx->extract_flags & WIMLIB_EXTRACT_FLAG_RESUME))
@@ -1435,18 +1437,15 @@ extract_streams_from_pipe(struct apply_ctx *ctx)
                }
 
                if ((found_lte->resource_location != RESOURCE_NONEXISTENT)
-                   && !(found_lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA)
+                   && !(found_lte->flags & WIM_RESHDR_FLAG_METADATA)
                    && (needed_lte = lookup_resource(lookup_table, found_lte->hash))
                    && (needed_lte->out_refcnt))
                {
-                       copy_resource_entry(&needed_lte->resource_entry,
-                                           &found_lte->resource_entry);
-                       needed_lte->resource_location = found_lte->resource_location;
-                       needed_lte->wim               = found_lte->wim;
-                       needed_lte->compression_type  = found_lte->compression_type;
-                       needed_lte->is_pipable        = found_lte->is_pipable;
-
+                       lte_unbind_wim_resource_spec(found_lte);
+                       lte_bind_wim_resource_spec(needed_lte, rspec);
                        ret = extract_stream_instances(needed_lte, ctx, false);
+                       lte_unbind_wim_resource_spec(needed_lte);
+
                        if (ret)
                                goto out_free_found_lte;
                        ctx->num_streams_remaining--;
@@ -1478,6 +1477,8 @@ extract_streams_from_pipe(struct apply_ctx *ctx)
        }
        ret = 0;
 out_free_found_lte:
+       if (found_lte->resource_location != RESOURCE_IN_WIM)
+               FREE(rspec);
        free_lookup_table_entry(found_lte);
 out:
        return ret;
@@ -1537,8 +1538,7 @@ extract_dentry_to_stdout(struct wim_dentry *dentry)
                if (lte) {
                        struct filedes _stdout;
                        filedes_init(&_stdout, STDOUT_FILENO);
-                       ret = extract_wim_resource_to_fd(lte, &_stdout,
-                                                        wim_resource_size(lte));
+                       ret = extract_wim_resource_to_fd(lte, &_stdout, lte->size);
                }
        }
        return ret;
@@ -2649,7 +2649,7 @@ extract_single_image(WIMStruct *wim, int image,
 {
        int ret;
        tchar *target_copy = canonicalize_fs_path(target);
-       if (!target_copy)
+       if (target_copy == NULL)
                return WIMLIB_ERR_NOMEM;
        struct wimlib_extract_command cmd = {
                .wim_source_path = T(""),
@@ -2821,11 +2821,12 @@ wimlib_extract_image_from_pipe(int pipe_fd, const tchar *image_num_or_name,
         * WIMs.)  */
        {
                struct wim_lookup_table_entry xml_lte;
-               ret = read_pwm_stream_header(pwm, &xml_lte, 0, NULL);
+               struct wim_resource_spec xml_rspec;
+               ret = read_pwm_stream_header(pwm, &xml_lte, &xml_rspec, 0, NULL);
                if (ret)
                        goto out_wimlib_free;
 
-               if (!(xml_lte.resource_entry.flags & WIM_RESHDR_FLAG_METADATA))
+               if (!(xml_lte.flags & WIM_RESHDR_FLAG_METADATA))
                {
                        ERROR("Expected XML data, but found non-metadata "
                              "stream.");
@@ -2833,12 +2834,12 @@ wimlib_extract_image_from_pipe(int pipe_fd, const tchar *image_num_or_name,
                        goto out_wimlib_free;
                }
 
-               copy_resource_entry(&pwm->hdr.xml_res_entry,
-                                   &xml_lte.resource_entry);
+               wim_res_spec_to_hdr(&xml_rspec, &pwm->hdr.xml_data_reshdr);
 
                ret = read_wim_xml_data(pwm);
                if (ret)
                        goto out_wimlib_free;
+
                if (wim_info_get_num_images(pwm->wim_info) != pwm->hdr.image_count) {
                        ERROR("Image count in XML data is not the same as in WIM header.");
                        ret = WIMLIB_ERR_XML;
@@ -2874,22 +2875,29 @@ wimlib_extract_image_from_pipe(int pipe_fd, const tchar *image_num_or_name,
        for (i = 1; i <= pwm->hdr.image_count; i++) {
                struct wim_lookup_table_entry *metadata_lte;
                struct wim_image_metadata *imd;
+               struct wim_resource_spec *metadata_rspec;
 
                metadata_lte = new_lookup_table_entry();
-               if (!metadata_lte) {
+               if (metadata_lte == NULL) {
                        ret = WIMLIB_ERR_NOMEM;
                        goto out_wimlib_free;
                }
+               metadata_rspec = MALLOC(sizeof(struct wim_resource_spec));
+               if (metadata_rspec == NULL) {
+                       ret = WIMLIB_ERR_NOMEM;
+                       free_lookup_table_entry(metadata_lte);
+                       goto out_wimlib_free;
+               }
 
-               ret = read_pwm_stream_header(pwm, metadata_lte, 0, NULL);
+               ret = read_pwm_stream_header(pwm, metadata_lte, metadata_rspec, 0, NULL);
                imd = pwm->image_metadata[i - 1];
                imd->metadata_lte = metadata_lte;
-               if (ret)
+               if (ret) {
+                       FREE(metadata_rspec);
                        goto out_wimlib_free;
+               }
 
-               if (!(metadata_lte->resource_entry.flags &
-                     WIM_RESHDR_FLAG_METADATA))
-               {
+               if (!(metadata_lte->flags & WIM_RESHDR_FLAG_METADATA)) {
                        ERROR("Expected metadata resource, but found "
                              "non-metadata stream.");
                        ret = WIMLIB_ERR_INVALID_PIPABLE_WIM;
index 4924b505dfba8f6e455733ddcb0e67722ba70e9f..d3ab360cd3502b4c641b153c62e5da992bc6c1da 100644 (file)
 /*
  * Reads the header from a WIM file.
  *
- * @filename
- *     Name of the WIM file (for error/debug messages only), or NULL if reading
- *     directly from file descriptor.
- * @in_fd
- *     File descriptor, positioned at offset 0, to read the header from.
+ * @wim
+ *     WIM to read the header from; @wim->in_fd must be positioned at the
+ *     offset at which to read the header.
+ *
  * @hdr
  *     Structure to read the header into.
  *
  * Return values:
  *     WIMLIB_ERR_SUCCESS (0)
  *     WIMLIB_ERR_IMAGE_COUNT
- *     WIMLIB_ERR_INVALID_CHUNK_SIZE
  *     WIMLIB_ERR_INVALID_PART_NUMBER
  *     WIMLIB_ERR_NOT_A_WIM_FILE
  *     WIMLIB_ERR_READ
  *     WIMLIB_ERR_UNKNOWN_VERSION
  */
 int
-read_wim_header(const tchar *filename, struct filedes *in_fd,
-               struct wim_header *hdr)
+read_wim_header(WIMStruct *wim, struct wim_header *hdr)
 {
        struct wim_header_disk disk_hdr _aligned_attribute(8);
+       struct filedes *in_fd = &wim->in_fd;
+       const tchar *filename = wim->filename;
        int ret;
        tchar *pipe_str;
 
@@ -113,14 +112,11 @@ read_wim_header(const tchar *filename, struct filedes *in_fd,
                return WIMLIB_ERR_INVALID_HEADER;
        }
 
-       if (le32_to_cpu(disk_hdr.wim_version) != WIM_VERSION) {
-               ERROR("\"%"TS"\": The WIM header says the WIM version is %u, "
-                     "but wimlib only knows about version %u",
-                     filename, le32_to_cpu(disk_hdr.wim_version), WIM_VERSION);
-               if (le32_to_cpu(disk_hdr.wim_flags) & WIM_HDR_FLAG_COMPRESS_LZMS) {
-                       ERROR("\"%"TS"\": This WIM uses LZMS compression, "
-                             "which is not supported by wimlib.", filename);
-               }
+       hdr->wim_version = le32_to_cpu(disk_hdr.wim_version);
+       if (hdr->wim_version != WIM_VERSION_DEFAULT &&
+           hdr->wim_version != WIM_VERSION_STREAM_CONCAT)
+       {
+               ERROR("\"%"TS"\": Unknown WIM version: %u", hdr->wim_version);
                return WIMLIB_ERR_UNKNOWN_VERSION;
        }
 
@@ -149,11 +145,11 @@ read_wim_header(const tchar *filename, struct filedes *in_fd,
                return WIMLIB_ERR_IMAGE_COUNT;
        }
 
-       get_resource_entry(&disk_hdr.lookup_table_res_entry, &hdr->lookup_table_res_entry);
-       get_resource_entry(&disk_hdr.xml_data_res_entry, &hdr->xml_res_entry);
-       get_resource_entry(&disk_hdr.boot_metadata_res_entry, &hdr->boot_metadata_res_entry);
+       get_wim_reshdr(&disk_hdr.lookup_table_reshdr, &hdr->lookup_table_reshdr);
+       get_wim_reshdr(&disk_hdr.xml_data_reshdr, &hdr->xml_data_reshdr);
+       get_wim_reshdr(&disk_hdr.boot_metadata_reshdr, &hdr->boot_metadata_reshdr);
        hdr->boot_idx = le32_to_cpu(disk_hdr.boot_idx);
-       get_resource_entry(&disk_hdr.integrity_table_res_entry, &hdr->integrity);
+       get_wim_reshdr(&disk_hdr.integrity_table_reshdr, &hdr->integrity_table_reshdr);
        return 0;
 
 read_error:
@@ -177,7 +173,7 @@ write_wim_header_at_offset(const struct wim_header *hdr, struct filedes *out_fd,
 
        disk_hdr.magic = hdr->magic;
        disk_hdr.hdr_size = cpu_to_le32(sizeof(struct wim_header_disk));
-       disk_hdr.wim_version = cpu_to_le32(WIM_VERSION);
+       disk_hdr.wim_version = cpu_to_le32(hdr->wim_version);
        disk_hdr.wim_flags = cpu_to_le32(hdr->flags);
        if (hdr->flags & WIM_HDR_FLAG_COMPRESSION)
                disk_hdr.chunk_size = cpu_to_le32(hdr->chunk_size);
@@ -188,11 +184,11 @@ write_wim_header_at_offset(const struct wim_header *hdr, struct filedes *out_fd,
        disk_hdr.part_number = cpu_to_le16(hdr->part_number);
        disk_hdr.total_parts = cpu_to_le16(hdr->total_parts);
        disk_hdr.image_count = cpu_to_le32(hdr->image_count);
-       put_resource_entry(&hdr->lookup_table_res_entry, &disk_hdr.lookup_table_res_entry);
-       put_resource_entry(&hdr->xml_res_entry, &disk_hdr.xml_data_res_entry);
-       put_resource_entry(&hdr->boot_metadata_res_entry, &disk_hdr.boot_metadata_res_entry);
+       put_wim_reshdr(&hdr->lookup_table_reshdr, &disk_hdr.lookup_table_reshdr);
+       put_wim_reshdr(&hdr->xml_data_reshdr, &disk_hdr.xml_data_reshdr);
+       put_wim_reshdr(&hdr->boot_metadata_reshdr, &disk_hdr.boot_metadata_reshdr);
        disk_hdr.boot_idx = cpu_to_le32(hdr->boot_idx);
-       put_resource_entry(&hdr->integrity, &disk_hdr.integrity_table_res_entry);
+       put_wim_reshdr(&hdr->integrity_table_reshdr, &disk_hdr.integrity_table_reshdr);
        memset(disk_hdr.unused, 0, sizeof(disk_hdr.unused));
 
        if (offset == out_fd->offset)
@@ -256,6 +252,7 @@ init_wim_header(struct wim_header *hdr, int ctype, u32 chunk_size)
 {
        memset(hdr, 0, sizeof(struct wim_header));
        hdr->magic = WIM_MAGIC;
+       hdr->wim_version = WIM_VERSION_DEFAULT;
        if (set_wim_hdr_cflags(ctype, hdr)) {
                ERROR("Invalid compression type specified (%d)", ctype);
                return WIMLIB_ERR_INVALID_COMPRESSION_TYPE;
@@ -293,51 +290,51 @@ wimlib_print_header(const WIMStruct *wim)
 
        tprintf(T("Magic Characters            = MSWIM\\000\\000\\000\n"));
        tprintf(T("Header Size                 = %u\n"), WIM_HEADER_DISK_SIZE);
-       tprintf(T("Version                     = 0x%x\n"), WIM_VERSION);
+       tprintf(T("Version                     = 0x%x\n"), hdr->wim_version);
 
        tprintf(T("Flags                       = 0x%x\n"), hdr->flags);
        for (size_t i = 0; i < ARRAY_LEN(hdr_flags); i++)
                if (hdr_flags[i].flag & hdr->flags)
                        tprintf(T("    WIM_HDR_FLAG_%s is set\n"), hdr_flags[i].name);
 
-       tprintf(T("Chunk Size                  = %u\n"), wim->hdr.chunk_size);
+       tprintf(T("Chunk Size                  = %u\n"), hdr->chunk_size);
        tfputs (T("GUID                        = "), stdout);
        print_byte_field(hdr->guid, WIM_GID_LEN, stdout);
        tputchar(T('\n'));
-       tprintf(T("Part Number                 = %hu\n"), wim->hdr.part_number);
-       tprintf(T("Total Parts                 = %hu\n"), wim->hdr.total_parts);
+       tprintf(T("Part Number                 = %hu\n"), hdr->part_number);
+       tprintf(T("Total Parts                 = %hu\n"), hdr->total_parts);
        tprintf(T("Image Count                 = %u\n"), hdr->image_count);
        tprintf(T("Lookup Table Size           = %"PRIu64"\n"),
-                               (u64)hdr->lookup_table_res_entry.size);
+                               (u64)hdr->lookup_table_reshdr.size_in_wim);
        tprintf(T("Lookup Table Flags          = 0x%hhx\n"),
-                               (u8)hdr->lookup_table_res_entry.flags);
+                               (u8)hdr->lookup_table_reshdr.flags);
        tprintf(T("Lookup Table Offset         = %"PRIu64"\n"),
-                               hdr->lookup_table_res_entry.offset);
+                               hdr->lookup_table_reshdr.offset_in_wim);
        tprintf(T("Lookup Table Original_size  = %"PRIu64"\n"),
-                               hdr->lookup_table_res_entry.original_size);
+                               hdr->lookup_table_reshdr.uncompressed_size);
        tprintf(T("XML Data Size               = %"PRIu64"\n"),
-                               (u64)hdr->xml_res_entry.size);
+                               (u64)hdr->xml_data_reshdr.size_in_wim);
        tprintf(T("XML Data Flags              = 0x%hhx\n"),
-                               (u8)hdr->xml_res_entry.flags);
+                               (u8)hdr->xml_data_reshdr.flags);
        tprintf(T("XML Data Offset             = %"PRIu64"\n"),
-                               hdr->xml_res_entry.offset);
+                               hdr->xml_data_reshdr.offset_in_wim);
        tprintf(T("XML Data Original Size      = %"PRIu64"\n"),
-                               hdr->xml_res_entry.original_size);
+                               hdr->xml_data_reshdr.uncompressed_size);
        tprintf(T("Boot Metadata Size          = %"PRIu64"\n"),
-                               (u64)hdr->boot_metadata_res_entry.size);
+                               (u64)hdr->boot_metadata_reshdr.size_in_wim);
        tprintf(T("Boot Metadata Flags         = 0x%hhx\n"),
-                               (u8)hdr->boot_metadata_res_entry.flags);
+                               (u8)hdr->boot_metadata_reshdr.flags);
        tprintf(T("Boot Metadata Offset        = %"PRIu64"\n"),
-                               hdr->boot_metadata_res_entry.offset);
+                               hdr->boot_metadata_reshdr.offset_in_wim);
        tprintf(T("Boot Metadata Original Size = %"PRIu64"\n"),
-                               hdr->boot_metadata_res_entry.original_size);
+                               hdr->boot_metadata_reshdr.uncompressed_size);
        tprintf(T("Boot Index                  = %u\n"), hdr->boot_idx);
        tprintf(T("Integrity Size              = %"PRIu64"\n"),
-                               (u64)hdr->integrity.size);
+                               (u64)hdr->integrity_table_reshdr.size_in_wim);
        tprintf(T("Integrity Flags             = 0x%hhx\n"),
-                               (u8)hdr->integrity.flags);
+                               (u8)hdr->integrity_table_reshdr.flags);
        tprintf(T("Integrity Offset            = %"PRIu64"\n"),
-                               hdr->integrity.offset);
+                               hdr->integrity_table_reshdr.offset_in_wim);
        tprintf(T("Integrity Original_size     = %"PRIu64"\n"),
-                               hdr->integrity.original_size);
+                               hdr->integrity_table_reshdr.uncompressed_size);
 }
index 21bc2f151ff314dea0fbfe3f241b8ee8aed1c3e4..8e1df18911f9d1d641e675cc95d2058f2fad17cd 100644 (file)
@@ -37,6 +37,7 @@
 #include "wimlib/resource.h"
 #include "wimlib/sha1.h"
 #include "wimlib/wim.h"
+#include "wimlib/write.h"
 
 /* Size, in bytes, of each SHA1-summed chunk, when wimlib writes integrity
  * information. */
@@ -87,9 +88,8 @@ calculate_chunk_sha1(struct filedes *in_fd, size_t this_chunk_size,
  * read_integrity_table: -  Reads the integrity table from a WIM file.
  *
  * @wim:
- *     WIMStruct for the WIM file; @wim->hdr.integrity specifies the location
- *     of the integrity table.  The integrity table must exist (i.e.
- *     res_entry->offset must not be 0).  @wim->in_fd is expected to be a
+ *     WIMStruct for the WIM file; @wim->hdr.integrity_table_reshdr specifies
+ *     the location of the integrity table.  @wim->in_fd is expected to be a
  *     seekable file descriptor to the WIM file opened for reading.
  *
  * @num_checked_bytes:
@@ -114,14 +114,12 @@ read_integrity_table(WIMStruct *wim, u64 num_checked_bytes,
        struct integrity_table *table;
        int ret;
 
-       if (wim->hdr.integrity.size < 8)
+       if (wim->hdr.integrity_table_reshdr.uncompressed_size < 8)
                goto invalid;
 
-       DEBUG("Reading integrity table (offset %"PRIu64", "
-             "original_size %"PRIu64")",
-             wim->hdr.integrity.offset, wim->hdr.integrity.original_size);
+       DEBUG("Reading integrity table.");
 
-       ret = res_entry_to_data(&wim->hdr.integrity, wim, &buf);
+       ret = wim_reshdr_to_data(&wim->hdr.integrity_table_reshdr, wim, &buf);
        if (ret)
                return ret;
        table = buf;
@@ -134,7 +132,7 @@ read_integrity_table(WIMStruct *wim, u64 num_checked_bytes,
              "table->chunk_size = %u",
              table->size, table->num_entries, table->chunk_size);
 
-       if (table->size != wim->hdr.integrity.original_size ||
+       if (table->size != wim->hdr.integrity_table_reshdr.uncompressed_size ||
            table->size != (u64)table->num_entries * SHA1_HASH_SIZE + 12 ||
            table->chunk_size == 0 ||
            table->num_entries != DIV_ROUND_UP(num_checked_bytes, table->chunk_size))
@@ -282,8 +280,8 @@ calculate_integrity_table(struct filedes *in_fd,
  * chunks of the file).
  *
  * This function can optionally re-use entries from an older integrity table.
- * To do this, make @integrity_res_entry point to the resource entry for the
- * older table (note: this is an input-output parameter), and set
+ * To do this, ensure that @wim->hdr.integrity_table_reshdr is the resource
+ * header for the older table (note: this is an input-output parameter), and set
  * @old_lookup_table_end to the offset of the byte directly following the last
  * byte checked by the old table.  If the old integrity table is invalid or
  * cannot be read, a warning is printed and the integrity information is
@@ -366,7 +364,7 @@ write_integrity_table(WIMStruct *wim,
                                             &wim->out_fd,
                                             WIMLIB_COMPRESSION_TYPE_NONE,
                                             0,
-                                            &wim->hdr.integrity,
+                                            &wim->hdr.integrity_table_reshdr,
                                             NULL,
                                             0,
                                             &wim->lzx_context);
@@ -486,8 +484,8 @@ check_wim_integrity(WIMStruct *wim, wimlib_progress_func_t progress_func)
                return WIM_INTEGRITY_NONEXISTENT;
        }
 
-       end_lookup_table_offset = wim->hdr.lookup_table_res_entry.offset +
-                                 wim->hdr.lookup_table_res_entry.size;
+       end_lookup_table_offset = wim->hdr.lookup_table_reshdr.offset_in_wim +
+                                 wim->hdr.lookup_table_reshdr.size_in_wim;
 
        if (end_lookup_table_offset < WIM_HEADER_DISK_SIZE) {
                ERROR("WIM lookup table ends before WIM header ends!");
index 302b1750ece3335c0dfda989c036efeb552e7d38..d08498f8371328f356a01ca4d5764a95f909cc88 100644 (file)
@@ -74,16 +74,15 @@ new_lookup_table_entry(void)
        struct wim_lookup_table_entry *lte;
 
        lte = CALLOC(1, sizeof(struct wim_lookup_table_entry));
-       if (lte) {
-               lte->part_number = 1;
-               lte->refcnt = 1;
-               BUILD_BUG_ON(RESOURCE_NONEXISTENT != 0);
-               BUILD_BUG_ON(WIMLIB_COMPRESSION_TYPE_NONE != 0);
-       } else {
+       if (lte == NULL) {
                ERROR("Out of memory (tried to allocate %zu bytes for "
                      "lookup table entry)",
                      sizeof(struct wim_lookup_table_entry));
+               return NULL;
        }
+       lte->refcnt = 1;
+       BUILD_BUG_ON(RESOURCE_NONEXISTENT != 0);
+       BUILD_BUG_ON(WIMLIB_COMPRESSION_TYPE_NONE != 0);
        return lte;
 }
 
@@ -98,6 +97,10 @@ clone_lookup_table_entry(const struct wim_lookup_table_entry *old)
 
        new->extracted_file = NULL;
        switch (new->resource_location) {
+       case RESOURCE_IN_WIM:
+               list_add(&new->wim_resource_list, &new->rspec->lte_list);
+               break;
+
        case RESOURCE_IN_FILE_ON_DISK:
 #ifdef __WIN32__
        case RESOURCE_WIN32_ENCRYPTED:
@@ -112,8 +115,7 @@ clone_lookup_table_entry(const struct wim_lookup_table_entry *old)
                        goto out_free;
                break;
        case RESOURCE_IN_ATTACHED_BUFFER:
-               new->attached_buffer = memdup(old->attached_buffer,
-                                             wim_resource_size(old));
+               new->attached_buffer = memdup(old->attached_buffer, old->size);
                if (!new->attached_buffer)
                        goto out_free;
                break;
@@ -153,6 +155,11 @@ free_lookup_table_entry(struct wim_lookup_table_entry *lte)
 {
        if (lte) {
                switch (lte->resource_location) {
+               case RESOURCE_IN_WIM:
+                       list_del(&lte->wim_resource_list);
+                       if (list_empty(&lte->rspec->lte_list))
+                               FREE(lte->rspec);
+                       break;
                case RESOURCE_IN_FILE_ON_DISK:
        #ifdef __WIN32__
                case RESOURCE_WIN32_ENCRYPTED:
@@ -303,6 +310,7 @@ cmp_streams_by_sequential_order(const void *p1, const void *p2)
 {
        const struct wim_lookup_table_entry *lte1, *lte2;
        int v;
+       WIMStruct *wim1, *wim2;
 
        lte1 = *(const struct wim_lookup_table_entry**)p1;
        lte2 = *(const struct wim_lookup_table_entry**)p2;
@@ -315,24 +323,25 @@ cmp_streams_by_sequential_order(const void *p1, const void *p2)
 
        switch (lte1->resource_location) {
        case RESOURCE_IN_WIM:
+               wim1 = lte1->rspec->wim;
+               wim2 = lte2->rspec->wim;
 
                /* Different (possibly split) WIMs?  */
-               if (lte1->wim != lte2->wim) {
-                       v = memcmp(lte1->wim->hdr.guid, lte2->wim->hdr.guid,
-                                  WIM_GID_LEN);
+               if (wim1 != wim2) {
+                       v = memcmp(wim1->hdr.guid, wim2->hdr.guid, WIM_GID_LEN);
                        if (v)
                                return v;
                }
 
                /* Different part numbers in the same WIM?  */
-               v = (int)lte1->wim->hdr.part_number - (int)lte2->wim->hdr.part_number;
+               v = (int)wim1->hdr.part_number - (int)wim2->hdr.part_number;
                if (v)
                        return v;
 
                /* Compare by offset.  */
-               if (lte1->resource_entry.offset < lte2->resource_entry.offset)
+               if (lte1->rspec->offset_in_wim < lte2->rspec->offset_in_wim)
                        return -1;
-               else if (lte1->resource_entry.offset > lte2->resource_entry.offset)
+               if (lte1->rspec->offset_in_wim > lte2->rspec->offset_in_wim)
                        return 1;
                return 0;
        case RESOURCE_IN_FILE_ON_DISK:
@@ -439,9 +448,8 @@ for_lookup_table_entry_pos_sorted(struct wim_lookup_table *table,
 
 /* On-disk format of a WIM lookup table entry (stream entry). */
 struct wim_lookup_table_entry_disk {
-       /* Location, offset, compression status, and metadata status of the
-        * stream. */
-       struct resource_entry_disk resource_entry;
+       /* Size, offset, and flags of the stream.  */
+       struct wim_reshdr_disk reshdr;
 
        /* Which part of the split WIM this stream is in; indexed from 1. */
        le16 part_number;
@@ -456,20 +464,6 @@ struct wim_lookup_table_entry_disk {
 
 #define WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE 50
 
-void
-lte_init_wim(struct wim_lookup_table_entry *lte, WIMStruct *wim)
-{
-       lte->resource_location = RESOURCE_IN_WIM;
-       lte->wim = wim;
-       if (lte->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED)
-               lte->compression_type = wim->compression_type;
-       else
-               lte->compression_type = WIMLIB_COMPRESSION_TYPE_NONE;
-
-       if (wim_is_pipable(wim))
-               lte->is_pipable = 1;
-}
-
 /*
  * Reads the lookup table from a WIM file.
  *
@@ -491,21 +485,19 @@ read_wim_lookup_table(WIMStruct *wim)
        struct wim_lookup_table *table;
        struct wim_lookup_table_entry *cur_entry, *duplicate_entry;
        void *buf;
+       bool in_concat_run;
 
        BUILD_BUG_ON(sizeof(struct wim_lookup_table_entry_disk) !=
                     WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE);
 
-       DEBUG("Reading lookup table: offset %"PRIu64", size %"PRIu64"",
-             wim->hdr.lookup_table_res_entry.offset,
-             wim->hdr.lookup_table_res_entry.size);
+       DEBUG("Reading lookup table.");
 
        /* Calculate number of entries in the lookup table.  */
-       num_entries = wim->hdr.lookup_table_res_entry.size /
+       num_entries = wim->hdr.lookup_table_reshdr.uncompressed_size /
                      sizeof(struct wim_lookup_table_entry_disk);
 
-
        /* Read the lookup table into a buffer.  */
-       ret = res_entry_to_data(&wim->hdr.lookup_table_res_entry, wim, &buf);
+       ret = wim_reshdr_to_data(&wim->hdr.lookup_table_reshdr, wim, &buf);
        if (ret)
                goto out;
 
@@ -520,33 +512,32 @@ read_wim_lookup_table(WIMStruct *wim)
        /* Allocate and initalize `struct wim_lookup_table_entry's from the
         * on-disk lookup table.  */
        wim->current_image = 0;
+       in_concat_run = false;
        for (i = 0; i < num_entries; i++) {
                const struct wim_lookup_table_entry_disk *disk_entry =
                        &((const struct wim_lookup_table_entry_disk*)buf)[i];
+               u16 part_number;
+               struct wim_reshdr reshdr;
+               struct wim_resource_spec *cur_rspec;
 
                cur_entry = new_lookup_table_entry();
-               if (!cur_entry) {
+               if (cur_entry == NULL) {
                        ERROR("Not enough memory to read lookup table.");
                        ret = WIMLIB_ERR_NOMEM;
                        goto out_free_lookup_table;
                }
 
-               cur_entry->wim = wim;
-               cur_entry->resource_location = RESOURCE_IN_WIM;
-               get_resource_entry(&disk_entry->resource_entry, &cur_entry->resource_entry);
-               cur_entry->part_number = le16_to_cpu(disk_entry->part_number);
+               part_number = le16_to_cpu(disk_entry->part_number);
                cur_entry->refcnt = le32_to_cpu(disk_entry->refcnt);
                copy_hash(cur_entry->hash, disk_entry->hash);
-               lte_init_wim(cur_entry, wim);
 
-               if (cur_entry->part_number != wim->hdr.part_number) {
+               if (part_number != wim->hdr.part_number) {
                        WARNING("A lookup table entry in part %hu of the WIM "
                                "points to part %hu (ignoring it)",
-                               wim->hdr.part_number, cur_entry->part_number);
+                               wim->hdr.part_number, part_number);
                        free_lookup_table_entry(cur_entry);
                        continue;
                }
-
                if (is_zero_hash(cur_entry->hash)) {
                        WARNING("The WIM lookup table contains an entry with a "
                                "SHA1 message digest of all 0's (ignoring it)");
@@ -554,29 +545,18 @@ read_wim_lookup_table(WIMStruct *wim)
                        continue;
                }
 
-               if (!(cur_entry->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED)
-                   && (cur_entry->resource_entry.size !=
-                       cur_entry->resource_entry.original_size))
-               {
-                       if (wimlib_print_errors) {
-                               WARNING("Found uncompressed resource with "
-                                       "original size (%"PRIu64") not the same "
-                                       "as compressed size (%"PRIu64")",
-                                       cur_entry->resource_entry.original_size,
-                                       cur_entry->resource_entry.size);
-                               if (cur_entry->resource_entry.original_size) {
-                                       WARNING("Overriding compressed size with original size.");
-                                       cur_entry->resource_entry.size =
-                                               cur_entry->resource_entry.original_size;
-                               } else {
-                                       WARNING("Overriding original size with compressed size");
-                                       cur_entry->resource_entry.original_size =
-                                               cur_entry->resource_entry.size;
-                               }
-                       }
+               cur_rspec = MALLOC(sizeof(struct wim_resource_spec));
+               if (cur_rspec == NULL) {
+                       ERROR("Not enough memory to read lookup table.");
+                       ret = WIMLIB_ERR_NOMEM;
+                       goto out_free_cur_entry;
                }
 
-               if (cur_entry->resource_entry.flags & WIM_RESHDR_FLAG_METADATA) {
+               get_wim_reshdr(&disk_entry->reshdr, &reshdr);
+               wim_res_hdr_to_spec(&reshdr, wim, cur_rspec);
+               lte_bind_wim_resource_spec(cur_entry, cur_rspec);
+
+               if (cur_entry->flags & WIM_RESHDR_FLAG_METADATA) {
                        /* Lookup table entry for a metadata resource */
                        if (cur_entry->refcnt != 1) {
                                /* Metadata entries with no references must be
@@ -619,7 +599,7 @@ read_wim_lookup_table(WIMStruct *wim)
                        DEBUG("Found metadata resource for image %u at "
                              "offset %"PRIu64".",
                              wim->current_image + 1,
-                             cur_entry->resource_entry.offset);
+                             cur_entry->rspec->offset_in_wim);
                        wim->image_metadata[
                                wim->current_image++]->metadata_lte = cur_entry;
                } else {
@@ -657,6 +637,7 @@ read_wim_lookup_table(WIMStruct *wim)
        wim->lookup_table = table;
        ret = 0;
        goto out_free_buf;
+
 out_free_cur_entry:
        FREE(cur_entry);
 out_free_lookup_table:
@@ -671,10 +652,11 @@ out:
 
 static void
 write_wim_lookup_table_entry(const struct wim_lookup_table_entry *lte,
-                            struct wim_lookup_table_entry_disk *disk_entry)
+                            struct wim_lookup_table_entry_disk *disk_entry,
+                            u16 part_number)
 {
-       put_resource_entry(&lte->output_resource_entry, &disk_entry->resource_entry);
-       disk_entry->part_number = cpu_to_le16(lte->part_number);
+       put_wim_reshdr(&lte->out_reshdr, &disk_entry->reshdr);
+       disk_entry->part_number = cpu_to_le16(part_number);
        disk_entry->refcnt = cpu_to_le32(lte->out_refcnt);
        copy_hash(disk_entry->hash, lte->hash);
 }
@@ -682,7 +664,8 @@ write_wim_lookup_table_entry(const struct wim_lookup_table_entry *lte,
 static int
 write_wim_lookup_table_from_stream_list(struct list_head *stream_list,
                                        struct filedes *out_fd,
-                                       struct resource_entry *out_res_entry,
+                                       u16 part_number,
+                                       struct wim_reshdr *out_reshdr,
                                        int write_resource_flags,
                                        struct wimlib_lzx_context **comp_ctx)
 {
@@ -707,7 +690,7 @@ write_wim_lookup_table_from_stream_list(struct list_head *stream_list,
        }
        table_buf_ptr = table_buf;
        list_for_each_entry(lte, stream_list, lookup_table_list)
-               write_wim_lookup_table_entry(lte, table_buf_ptr++);
+               write_wim_lookup_table_entry(lte, table_buf_ptr++, part_number);
 
        /* Write the lookup table uncompressed.  Although wimlib can handle a
         * compressed lookup table, MS software cannot.  */
@@ -717,7 +700,7 @@ write_wim_lookup_table_from_stream_list(struct list_head *stream_list,
                                             out_fd,
                                             WIMLIB_COMPRESSION_TYPE_NONE,
                                             0,
-                                            out_res_entry,
+                                            out_reshdr,
                                             NULL,
                                             write_resource_flags,
                                             comp_ctx);
@@ -746,10 +729,8 @@ append_lookup_table_entry(struct wim_lookup_table_entry *lte, void *_list)
         * needs to be copied from the resource information read originally.
         */
        if (lte->out_refcnt != 0 && !(lte->filtered & FILTERED_EXTERNAL_WIM)) {
-               if (lte->filtered & FILTERED_SAME_WIM) {
-                       copy_resource_entry(&lte->output_resource_entry,
-                                           &lte->resource_entry);
-               }
+               if (lte->filtered & FILTERED_SAME_WIM)
+                       wim_res_spec_to_hdr(lte->rspec, &lte->out_reshdr);
                list_add_tail(&lte->lookup_table_list, (struct list_head*)_list);
        }
        return 0;
@@ -757,7 +738,7 @@ append_lookup_table_entry(struct wim_lookup_table_entry *lte, void *_list)
 
 int
 write_wim_lookup_table(WIMStruct *wim, int image, int write_flags,
-                      struct resource_entry *out_res_entry,
+                      struct wim_reshdr *out_reshdr,
                       struct list_head *stream_list_override)
 {
        int write_resource_flags;
@@ -791,9 +772,7 @@ write_wim_lookup_table(WIMStruct *wim, int image, int write_flags,
 
                        metadata_lte = wim->image_metadata[i - 1]->metadata_lte;
                        metadata_lte->out_refcnt = 1;
-                       metadata_lte->part_number = wim->hdr.part_number;
-                       metadata_lte->output_resource_entry.flags |= WIM_RESHDR_FLAG_METADATA;
-
+                       metadata_lte->out_reshdr.flags |= WIM_RESHDR_FLAG_METADATA;
                        list_add(&metadata_lte->lookup_table_list, stream_list);
                }
        }
@@ -811,7 +790,8 @@ write_wim_lookup_table(WIMStruct *wim, int image, int write_flags,
                write_resource_flags |= WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE;
        return write_wim_lookup_table_from_stream_list(stream_list,
                                                       &wim->out_fd,
-                                                      out_res_entry,
+                                                      wim->hdr.part_number,
+                                                      out_reshdr,
                                                       write_resource_flags,
                                                       &wim->lzx_context);
 }
@@ -844,21 +824,21 @@ lte_free_extracted_file(struct wim_lookup_table_entry *lte, void *_ignore)
 void
 print_lookup_table_entry(const struct wim_lookup_table_entry *lte, FILE *out)
 {
-       if (!lte) {
+       if (lte == NULL) {
                tputc(T('\n'), out);
                return;
        }
-       tfprintf(out, T("Offset            = %"PRIu64" bytes\n"),
-                lte->resource_entry.offset);
 
-       tfprintf(out, T("Size              = %"PRIu64" bytes\n"),
-                (u64)lte->resource_entry.size);
+       tfprintf(out, T("Reference Count    = %u\n"), lte->refcnt);
+       tfprintf(out, T("Uncompressed Size  = %"PRIu64" bytes\n"), lte->size);
 
-       tfprintf(out, T("Original size     = %"PRIu64" bytes\n"),
-                lte->resource_entry.original_size);
+       if (lte->resource_location == RESOURCE_IN_WIM) {
+               tfprintf(out, T("Offset in WIM    = %"PRIu64" bytes\n"),
+                        lte->rspec->offset_in_wim);
 
-       tfprintf(out, T("Part Number       = %hu\n"), lte->part_number);
-       tfprintf(out, T("Reference Count   = %u\n"), lte->refcnt);
+               tfprintf(out, T("Size in WIM      = %"PRIu64" bytes\n"),
+                        lte->rspec->size_in_wim);
+       }
 
        if (lte->unhashed) {
                tfprintf(out, T("(Unhashed: inode %p, stream_id = %u)\n"),
@@ -870,7 +850,7 @@ print_lookup_table_entry(const struct wim_lookup_table_entry *lte, FILE *out)
        }
 
        tfprintf(out, T("Flags             = "));
-       u8 flags = lte->resource_entry.flags;
+       u8 flags = lte->flags;
        if (flags & WIM_RESHDR_FLAG_COMPRESSED)
                tfputs(T("WIM_RESHDR_FLAG_COMPRESSED, "), out);
        if (flags & WIM_RESHDR_FLAG_FREE)
@@ -879,12 +859,14 @@ print_lookup_table_entry(const struct wim_lookup_table_entry *lte, FILE *out)
                tfputs(T("WIM_RESHDR_FLAG_METADATA, "), out);
        if (flags & WIM_RESHDR_FLAG_SPANNED)
                tfputs(T("WIM_RESHDR_FLAG_SPANNED, "), out);
+       if (flags & WIM_RESHDR_FLAG_CONCAT)
+               tfputs(T("WIM_RESHDR_FLAG_CONCAT, "), out);
        tputc(T('\n'), out);
        switch (lte->resource_location) {
        case RESOURCE_IN_WIM:
-               if (lte->wim->filename) {
+               if (lte->rspec->wim->filename) {
                        tfprintf(out, T("WIM file          = `%"TS"'\n"),
-                                lte->wim->filename);
+                                lte->rspec->wim->filename);
                }
                break;
 #ifdef __WIN32__
@@ -910,16 +892,23 @@ 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;
+       wentry->uncompressed_size = lte->size;
+
+       if (lte->resource_location == RESOURCE_IN_WIM) {
+               wentry->compressed_size = lte->rspec->size_in_wim;
+               wentry->offset = lte->rspec->offset_in_wim;
+               wentry->part_number = lte->rspec->wim->hdr.part_number;
+       } else {
+               wentry->compressed_size = 0;
+               wentry->offset = 0;
+               wentry->part_number = 0;
+       }
        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;
+       wentry->is_compressed = (lte->flags & WIM_RESHDR_FLAG_COMPRESSED) != 0;
+       wentry->is_metadata = (lte->flags & WIM_RESHDR_FLAG_METADATA) != 0;
+       wentry->is_free = (lte->flags & WIM_RESHDR_FLAG_FREE) != 0;
+       wentry->is_spanned = (lte->flags & WIM_RESHDR_FLAG_SPANNED) != 0;
 }
 
 struct iterate_lte_context {
@@ -1257,22 +1246,6 @@ inode_unnamed_stream_hash(const struct wim_inode *inode)
        return zero_hash;
 }
 
-
-static int
-lte_add_stream_size(struct wim_lookup_table_entry *lte, void *total_bytes_p)
-{
-       *(u64*)total_bytes_p += lte->resource_entry.size;
-       return 0;
-}
-
-u64
-lookup_table_total_stream_size(struct wim_lookup_table *table)
-{
-       u64 total_size = 0;
-       for_lookup_table_entry(table, lte_add_stream_size, &total_size);
-       return total_size;
-}
-
 struct wim_lookup_table_entry **
 retrieve_lte_pointer(struct wim_lookup_table_entry *lte)
 {
index 5ee296642fb70651b5a9c609d8571099bb968d40..b5ed165ccde0955f2dbd9bfc7068c716dc8647a2 100644 (file)
@@ -31,6 +31,7 @@
 #include "wimlib/metadata.h"
 #include "wimlib/resource.h"
 #include "wimlib/security.h"
+#include "wimlib/write.h"
 
 /*
  * Reads a metadata resource for an image in the WIM file.  The metadata
@@ -71,13 +72,13 @@ read_metadata_resource(WIMStruct *wim, struct wim_image_metadata *imd)
        struct wim_inode *inode;
 
        metadata_lte = imd->metadata_lte;
-       metadata_len = wim_resource_size(metadata_lte);
+       metadata_len = metadata_lte->size;
 
        DEBUG("Reading metadata resource: original_size = %"PRIu64", "
              "size = %"PRIu64", offset = %"PRIu64"",
-             metadata_lte->resource_entry.original_size,
-             metadata_lte->resource_entry.size,
-             metadata_lte->resource_entry.offset);
+             metadata_lte->rspec->uncompressed_size,
+             metadata_lte->rspec->size_in_wim,
+             metadata_lte->rspec->offset_in_wim);
 
        /* There is no way the metadata resource could possibly be less than (8
         * + WIM_DENTRY_DISK_SIZE) bytes, where the 8 is for security data (with
@@ -298,7 +299,7 @@ write_metadata_resource(WIMStruct *wim, int image, int write_resource_flags)
                                             &wim->out_fd,
                                             wim->out_compression_type,
                                             wim->out_chunk_size,
-                                            &imd->metadata_lte->output_resource_entry,
+                                            &imd->metadata_lte->out_reshdr,
                                             imd->metadata_lte->hash,
                                             write_resource_flags,
                                             &wim->lzx_context);
index ce4a58432d51f081256a26c550c1fb5d369895fa..b1a3f1c7ca7bcf9e72e82d3a81ed75b0aa2603af 100644 (file)
@@ -434,7 +434,7 @@ inode_to_stbuf(const struct wim_inode *inode,
        stbuf->st_ino = (ino_t)inode->i_ino;
        stbuf->st_nlink = inode->i_nlink;
        if (lte)
-               stbuf->st_size = wim_resource_size(lte);
+               stbuf->st_size = lte->size;
        else
                stbuf->st_size = 0;
 #ifdef HAVE_STAT_NANOSECOND_PRECISION
@@ -568,7 +568,7 @@ extract_resource_to_staging_dir(struct wim_inode *inode,
        if (old_lte) {
                struct filedes wimlib_fd;
                filedes_init(&wimlib_fd, fd);
-               extract_size = min(wim_resource_size(old_lte), size);
+               extract_size = min(old_lte->size, size);
                ret = extract_wim_resource_to_fd(old_lte, &wimlib_fd,
                                                 extract_size);
        } else {
@@ -663,10 +663,10 @@ extract_resource_to_staging_dir(struct wim_inode *inode,
                }
        }
 
-       new_lte->refcnt                       = inode->i_nlink;
-       new_lte->resource_location            = RESOURCE_IN_STAGING_FILE;
-       new_lte->staging_file_name            = staging_file_name;
-       new_lte->resource_entry.original_size = size;
+       new_lte->refcnt              = inode->i_nlink;
+       new_lte->resource_location   = RESOURCE_IN_STAGING_FILE;
+       new_lte->staging_file_name   = staging_file_name;
+       new_lte->size                = size;
 
        lookup_table_insert_unhashed(ctx->wim->lookup_table, new_lte,
                                     inode, stream_id);
@@ -825,7 +825,7 @@ rebuild_wim(struct wimfs_context *ctx, int write_flags,
        DEBUG("Freeing entries for zero-length streams");
        image_for_each_unhashed_stream_safe(lte, tmp, imd) {
                wimlib_assert(lte->unhashed);
-               if (wim_resource_size(lte) == 0) {
+               if (lte->size == 0) {
                        struct wim_lookup_table_entry **back_ptr;
                        back_ptr = retrieve_lte_pointer(lte);
                        *back_ptr = NULL;
@@ -1606,7 +1606,7 @@ wimfs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi)
        if (ret)
                return -errno;
        touch_inode(fd->f_inode);
-       fd->f_lte->resource_entry.original_size = size;
+       fd->f_lte->size = size;
        return 0;
 }
 
@@ -1639,7 +1639,7 @@ wimfs_getxattr(const char *path, const char *name, char *value,
        int ret;
        struct wim_inode *inode;
        struct wim_ads_entry *ads_entry;
-       size_t res_size;
+       u64 stream_size;
        struct wim_lookup_table_entry *lte;
        struct wimfs_context *ctx = wimfs_get_context();
 
@@ -1659,12 +1659,12 @@ wimfs_getxattr(const char *path, const char *name, char *value,
                return -ENOATTR;
 
        lte = ads_entry->lte;
-       res_size = wim_resource_size(lte);
+       stream_size = lte->size;
 
        if (size == 0)
-               return res_size;
+               return stream_size;
 
-       if (res_size > size)
+       if (stream_size > size)
                return -ERANGE;
 
        ret = read_full_resource_into_buf(lte, value);
@@ -1674,7 +1674,7 @@ wimfs_getxattr(const char *path, const char *name, char *value,
                else
                        return -EIO;
        }
-       return res_size;
+       return stream_size;
 }
 #endif
 
@@ -1857,7 +1857,7 @@ wimfs_open(const char *path, struct fuse_file_info *fi)
 
        if (flags_writable(fi->flags) &&
             (!lte || lte->resource_location != RESOURCE_IN_STAGING_FILE)) {
-               u64 size = (lte) ? wim_resource_size(lte) : 0;
+               u64 size = (lte) ? lte->size : 0;
                ret = extract_resource_to_staging_dir(inode, stream_id,
                                                      &lte, size, ctx);
                if (ret)
@@ -1915,7 +1915,7 @@ wimfs_read(const char *path, char *buf, size_t size,
 {
        struct wimfs_fd *fd = (struct wimfs_fd*)(uintptr_t)fi->fh;
        ssize_t ret;
-       u64 res_size;
+       u64 stream_size;
 
        if (!fd)
                return -EBADF;
@@ -1924,14 +1924,14 @@ wimfs_read(const char *path, char *buf, size_t size,
                return 0;
 
        if (fd->f_lte)
-               res_size = wim_resource_size(fd->f_lte);
+               stream_size = fd->f_lte->size;
        else
-               res_size = 0;
+               stream_size = 0;
 
-       if (offset > res_size)
+       if (offset > stream_size)
                return -EOVERFLOW;
 
-       size = min(size, res_size - offset);
+       size = min(size, stream_size - offset);
        if (size == 0)
                return 0;
 
@@ -2205,7 +2205,7 @@ wimfs_truncate(const char *path, off_t size)
                if (ret)
                        ret = -errno;
                else
-                       lte->resource_entry.original_size = size;
+                       lte->size = size;
        } else {
                /* File in WIM.  Extract it to the staging directory, but only
                 * the first @size bytes of it. */
@@ -2325,11 +2325,10 @@ wimfs_write(const char *path, const char *buf, size_t size,
                return -errno;
 
        /* Update file size */
-       if (offset + size > fd->f_lte->resource_entry.original_size) {
+       if (offset + size > fd->f_lte->size) {
                DEBUG("Update file size %"PRIu64 " => %"PRIu64"",
-                     fd->f_lte->resource_entry.original_size,
-                     offset + size);
-               fd->f_lte->resource_entry.original_size = offset + size;
+                     fd->f_lte->size, offset + size);
+               fd->f_lte->size = offset + size;
        }
 
        /* Update timestamps */
index 356f5fe7b61cbca6374a0365e681729fd8fb2c5a..b49e53a7ea84651f75aa978095c14addcdbdef11 100644 (file)
@@ -261,13 +261,13 @@ ntfs_3g_extract_stream(file_spec_t file, const utf16lechar *raw_stream_name,
         * to skip even more useless work (for example it fills resized
         * attributes with 0's, then we just override it.)  */
        ret = WIMLIB_ERR_WRITE;
-       if (ntfs_attr_truncate_solid(na, wim_resource_size(lte)))
+       if (ntfs_attr_truncate_solid(na, lte->size))
                goto out_attr_close;
 
        /* Extract stream data to the NTFS attribute.  */
        extract_ctx.na = na;
        extract_ctx.offset = 0;
-       ret = extract_wim_resource(lte, wim_resource_size(lte),
+       ret = extract_wim_resource(lte, lte->size,
                                   ntfs_3g_extract_wim_chunk, &extract_ctx);
        /* Clean up and return.  */
 out_attr_close:
index 6daf0a54720afaa2a31bb1a75bfbc4546c213d1f..829c41c963a7d6b396fecebef6a81d24e59632d7 100644 (file)
@@ -258,14 +258,14 @@ capture_ntfs_streams(struct wim_inode *inode,
                                        goto out_free_lte;
                                }
                                lte->ntfs_loc->is_reparse_point = true;
-                               lte->resource_entry.original_size = data_size - 8;
+                               lte->size = data_size - 8;
                                ret = read_reparse_tag(ni, lte->ntfs_loc,
                                                       &inode->i_reparse_tag);
                                if (ret)
                                        goto out_free_lte;
                        } else {
                                lte->ntfs_loc->is_reparse_point = false;
-                               lte->resource_entry.original_size = data_size;
+                               lte->size = data_size;
                        }
                }
                if (name_length == 0) {
@@ -275,8 +275,8 @@ capture_ntfs_streams(struct wim_inode *inode,
                                if (lte) {
                                        ERROR("Found two un-named data streams for \"%s\" "
                                              "(sizes = %"PRIu64", %"PRIu64")",
-                                             path, wim_resource_size(inode->i_lte),
-                                             wim_resource_size(lte));
+                                             path, inode->i_lte->size,
+                                             lte->size);
                                        ret = WIMLIB_ERR_NTFS_3G;
                                        goto out_free_lte;
                                }
index 1cbca56f146610f966df66a458346966e3c2c4a4..cbb3a08c11aaae2b3fc115cfa51c2cd102df3117 100644 (file)
@@ -292,11 +292,11 @@ wim_inode_get_reparse_data(const struct wim_inode * restrict inode,
                lte = lte_override;
        }
 
-       if (wim_resource_size(lte) > REPARSE_POINT_MAX_SIZE - 8) {
+       if (lte->size > REPARSE_POINT_MAX_SIZE - 8) {
                ERROR("Reparse data is too long!");
                return WIMLIB_ERR_INVALID_REPARSE_DATA;
        }
-       rpdatalen = wim_resource_size(lte);
+       rpdatalen = lte->size;
 
        /* Read the data from the WIM file */
        ret = read_full_resource_into_buf(lte, rpbuf + 8);
index 892aff18dc0852909fda70a96103b0a6dd4f5c31..d88974488fa5136d4868554e0d36fbde7a7ec8c9 100644 (file)
@@ -120,7 +120,7 @@ decompress(const void *cchunk, unsigned clen,
 /* Read data from a compressed WIM resource.  Assumes parameters were already
  * verified by read_partial_wim_resource().  */
 static int
-read_compressed_wim_resource(const struct wim_lookup_table_entry * const lte,
+read_compressed_wim_resource(const struct wim_resource_spec * const rspec,
                             const u64 size, const consume_data_callback_t cb,
                             const u32 cb_chunk_size, void * const ctx_or_buf,
                             const int flags, const u64 offset)
@@ -128,7 +128,7 @@ read_compressed_wim_resource(const struct wim_lookup_table_entry * const lte,
        int ret;
        int errno_save;
 
-       const u32 orig_chunk_size = wim_resource_chunk_size(lte);
+       const u32 orig_chunk_size = rspec->cchunk_size;
        const u32 orig_chunk_order = bsr32(orig_chunk_size);
 
        wimlib_assert(is_power_of_2(orig_chunk_size));
@@ -147,13 +147,13 @@ read_compressed_wim_resource(const struct wim_lookup_table_entry * const lte,
        bool compressed_buf_malloced = false;
 
        /* Get the file descriptor for the WIM.  */
-       struct filedes * const in_fd = &lte->wim->in_fd;
+       struct filedes * const in_fd = &rspec->wim->in_fd;
 
        /* Determine if we're reading a pipable resource from a pipe or not.  */
        const bool is_pipe_read = !filedes_is_seekable(in_fd);
 
        /* Calculate the number of chunks the resource is divided into.  */
-       const u64 num_chunks = wim_resource_chunks(lte);
+       const u64 num_chunks = (rspec->uncompressed_size + orig_chunk_size - 1) >> orig_chunk_order;
 
        /* Calculate the 0-based index of the chunk at which the read starts.
         */
@@ -180,13 +180,13 @@ read_compressed_wim_resource(const struct wim_lookup_table_entry * const lte,
 
        /* Set the size of each chunk table entry based on the resource's
         * uncompressed size.  */
-       const u64 chunk_entry_size = (wim_resource_size(lte) > (1ULL << 32)) ? 8 : 4;
+       const u64 chunk_entry_size = (rspec->uncompressed_size > (1ULL << 32)) ? 8 : 4;
 
        /* Calculate the size, in bytes, of the full chunk table.  */
        const u64 chunk_table_size = num_chunk_entries * chunk_entry_size;
 
        /* Current offset to read from.  */
-       u64 cur_read_offset = lte->resource_entry.offset;
+       u64 cur_read_offset = rspec->offset_in_wim;
        if (!is_pipe_read) {
                /* Read the chunk table into memory.  */
 
@@ -242,9 +242,9 @@ read_compressed_wim_resource(const struct wim_lookup_table_entry * const lte,
                 * file is in the special "pipable" format, then the chunk table
                 * is at the end of the resource, not the beginning.  */
                const u64 file_offset_of_needed_chunk_entries =
-                       lte->resource_entry.offset
+                       rspec->offset_in_wim
                        + (start_table_idx * chunk_entry_size)
-                       + (lte->is_pipable ? (lte->resource_entry.size - chunk_table_size) : 0);
+                       + (rspec->is_pipable ? (rspec->size_in_wim - chunk_table_size) : 0);
 
                /* Read the needed chunk table entries into the end of the
                 * chunk_offsets buffer.  */
@@ -282,7 +282,7 @@ read_compressed_wim_resource(const struct wim_lookup_table_entry * const lte,
 
                /* Set offset to beginning of first chunk to read.  */
                cur_read_offset += chunk_offsets[0];
-               if (lte->is_pipable)
+               if (rspec->is_pipable)
                        cur_read_offset += start_chunk * sizeof(struct pwm_chunk_hdr);
                else
                        cur_read_offset += chunk_table_size;
@@ -330,7 +330,7 @@ read_compressed_wim_resource(const struct wim_lookup_table_entry * const lte,
         * chunks for which only part of the data is needed.  */
        if (start_offset_in_chunk != 0 ||
            (end_offset_in_chunk != orig_chunk_size - 1 &&
-            offset + size != wim_resource_size(lte)))
+            offset + size != rspec->uncompressed_size))
        {
                if (orig_chunk_size <= STACK_MAX) {
                        tmp_buf = alloca(orig_chunk_size);
@@ -349,8 +349,8 @@ read_compressed_wim_resource(const struct wim_lookup_table_entry * const lte,
 
                /* Calculate uncompressed size of next chunk.  */
                u32 chunk_usize;
-               if ((i == num_chunks - 1) && (wim_resource_size(lte) & (orig_chunk_size - 1)))
-                       chunk_usize = (wim_resource_size(lte) & (orig_chunk_size - 1));
+               if ((i == num_chunks - 1) && (rspec->uncompressed_size & (orig_chunk_size - 1)))
+                       chunk_usize = (rspec->uncompressed_size & (orig_chunk_size - 1));
                else
                        chunk_usize = orig_chunk_size;
 
@@ -366,10 +366,10 @@ read_compressed_wim_resource(const struct wim_lookup_table_entry * const lte,
                        chunk_csize = le32_to_cpu(chunk_hdr.compressed_size);
                } else {
                        if (i == num_chunks - 1) {
-                               chunk_csize = lte->resource_entry.size -
+                               chunk_csize = rspec->size_in_wim -
                                              chunk_table_size -
                                              chunk_offsets[i - start_chunk];
-                               if (lte->is_pipable)
+                               if (rspec->is_pipable)
                                        chunk_csize -= num_chunks * sizeof(struct pwm_chunk_hdr);
                        } else {
                                chunk_csize = chunk_offsets[i + 1 - start_chunk] -
@@ -382,7 +382,7 @@ read_compressed_wim_resource(const struct wim_lookup_table_entry * const lte,
                        ret = WIMLIB_ERR_DECOMPRESSION;
                        goto out_free_memory;
                }
-               if (lte->is_pipable)
+               if (rspec->is_pipable)
                        cur_read_offset += sizeof(struct pwm_chunk_hdr);
 
                if (i >= start_chunk) {
@@ -435,7 +435,7 @@ read_compressed_wim_resource(const struct wim_lookup_table_entry * const lte,
                                                 chunk_csize,
                                                 target,
                                                 chunk_usize,
-                                                wim_resource_compression_type(lte),
+                                                rspec->ctype,
                                                 orig_chunk_size);
                                if (ret) {
                                        ERROR("Failed to decompress data!");
@@ -484,7 +484,7 @@ read_compressed_wim_resource(const struct wim_lookup_table_entry * const lte,
        }
 
        if (is_pipe_read
-           && size == lte->resource_entry.original_size
+           && size == rspec->uncompressed_size
            && chunk_table_size)
        {
                u8 dummy;
@@ -613,49 +613,52 @@ read_partial_wim_resource(const struct wim_lookup_table_entry *lte,
                          u32 cb_chunk_size,
                          void *ctx_or_buf, int flags, u64 offset)
 {
+       const struct wim_resource_spec *rspec;
        struct filedes *in_fd;
 
        /* Verify parameters.  */
        wimlib_assert(lte->resource_location == RESOURCE_IN_WIM);
-       in_fd = &lte->wim->in_fd;
+       rspec = lte->rspec;
+       in_fd = &rspec->wim->in_fd;
        if (cb)
                wimlib_assert(is_power_of_2(cb_chunk_size));
        if (flags & WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS) {
                /* Raw chunks mode is subject to the restrictions noted.  */
                wimlib_assert(!(flags & WIMLIB_READ_RESOURCE_FLAG_RAW_FULL));
-               wimlib_assert(cb_chunk_size == wim_resource_chunk_size(lte));
-               wimlib_assert(size == lte->resource_entry.original_size);
+               wimlib_assert(cb_chunk_size == rspec->cchunk_size);
+               wimlib_assert(size == rspec->uncompressed_size);
                wimlib_assert(offset == 0);
        } else if (flags & WIMLIB_READ_RESOURCE_FLAG_RAW_FULL) {
                /* Raw full mode:  read must not overrun end of store size.  */
                wimlib_assert(offset + size >= size &&
-                             offset + size <= lte->resource_entry.size);
+                             offset + size <= rspec->size_in_wim);
        } else {
                /* Normal mode:  read must not overrun end of original size.  */
                wimlib_assert(offset + size >= size &&
-                             offset + size <= lte->resource_entry.original_size);
+                             offset + size <= rspec->uncompressed_size);
        }
 
        DEBUG("Reading WIM resource: %"PRIu64" @ +%"PRIu64" "
              "from %"PRIu64"(%"PRIu64") @ +%"PRIu64" "
              "(readflags 0x%08x, resflags 0x%02x%s)",
              size, offset,
-             lte->resource_entry.size,
-             lte->resource_entry.original_size,
-             lte->resource_entry.offset,
-             flags, lte->resource_entry.flags,
-             (lte->is_pipable ? ", pipable" : ""));
+             rspec->size_in_wim,
+             rspec->uncompressed_size,
+             rspec->offset_in_wim,
+             flags, lte->flags,
+             (rspec->is_pipable ? ", pipable" : ""));
 
        if ((flags & WIMLIB_READ_RESOURCE_FLAG_RAW_FULL) ||
-           !resource_is_compressed(&lte->resource_entry)) {
+           rspec->ctype == WIMLIB_COMPRESSION_TYPE_NONE)
+       {
                return read_raw_file_data(in_fd,
                                          size,
                                          cb,
                                          cb_chunk_size,
                                          ctx_or_buf,
-                                         offset + lte->resource_entry.offset);
+                                         offset + rspec->offset_in_wim);
        } else {
-               return read_compressed_wim_resource(lte, size, cb,
+               return read_compressed_wim_resource(rspec, size, cb,
                                                    cb_chunk_size,
                                                    ctx_or_buf, flags, offset);
        }
@@ -702,7 +705,7 @@ read_file_on_disk_prefix(const struct wim_lookup_table_entry *lte,
        int raw_fd;
        struct filedes fd;
 
-       wimlib_assert(size <= wim_resource_size(lte));
+       wimlib_assert(size <= lte->size);
        DEBUG("Reading %"PRIu64" bytes from \"%"TS"\"", size, lte->file_on_disk);
 
        raw_fd = open(lte->file_on_disk, O_BINARY | O_RDONLY);
@@ -725,7 +728,7 @@ read_buffer_prefix(const struct wim_lookup_table_entry *lte,
                   u32 cb_chunk_size,
                   void *ctx_or_buf, int _ignored_flags)
 {
-       wimlib_assert(size <= wim_resource_size(lte));
+       wimlib_assert(size <= lte->size);
 
        if (cb) {
                /* Feed the data into the callback function in
@@ -820,8 +823,7 @@ int
 read_full_resource_into_buf(const struct wim_lookup_table_entry *lte,
                            void *buf)
 {
-       return read_resource_prefix(lte, wim_resource_size(lte),
-                                   NULL, 0, buf, 0);
+       return read_resource_prefix(lte, lte->size, NULL, 0, buf, 0);
 }
 
 /* Read the full uncompressed data of the specified resource.  A buffer
@@ -833,15 +835,13 @@ read_full_resource_into_alloc_buf(const struct wim_lookup_table_entry *lte,
        int ret;
        void *buf;
 
-       if ((size_t)lte->resource_entry.original_size !=
-           lte->resource_entry.original_size)
-       {
+       if ((size_t)lte->size != lte->size) {
                ERROR("Can't read %"PRIu64" byte resource into "
-                     "memory", lte->resource_entry.original_size);
+                     "memory", lte->size);
                return WIMLIB_ERR_NOMEM;
        }
 
-       buf = MALLOC(lte->resource_entry.original_size);
+       buf = MALLOC(lte->size);
        if (buf == NULL)
                return WIMLIB_ERR_NOMEM;
 
@@ -857,9 +857,8 @@ read_full_resource_into_alloc_buf(const struct wim_lookup_table_entry *lte,
 
 /* Retrieve the full uncompressed data of the specified WIM resource, provided
  * as a raw `struct resource_entry'.  */
-int
-res_entry_to_data(const struct resource_entry *res_entry,
-                 WIMStruct *wim, void **buf_ret)
+static int
+wim_resource_spec_to_data(struct wim_resource_spec *rspec, void **buf_ret)
 {
        int ret;
        struct wim_lookup_table_entry *lte;
@@ -868,16 +867,28 @@ res_entry_to_data(const struct resource_entry *res_entry,
        if (lte == NULL)
                return WIMLIB_ERR_NOMEM;
 
-       copy_resource_entry(&lte->resource_entry, res_entry);
        lte->unhashed = 1;
-       lte->part_number = wim->hdr.part_number;
-       lte_init_wim(lte, wim);
+       lte_bind_wim_resource_spec(lte, rspec);
 
        ret = read_full_resource_into_alloc_buf(lte, buf_ret);
+
+       lte_unbind_wim_resource_spec(lte);
        free_lookup_table_entry(lte);
        return ret;
 }
 
+int
+wim_reshdr_to_data(const struct wim_reshdr *reshdr, WIMStruct *wim, void **buf_ret)
+{
+       DEBUG("offset_in_wim=%"PRIu64", size_in_wim=%"PRIu64", "
+             "uncompressed_size=%"PRIu64,
+             reshdr->offset_in_wim, reshdr->size_in_wim, reshdr->uncompressed_size);
+
+       struct wim_resource_spec rspec;
+       wim_res_hdr_to_spec(reshdr, wim, &rspec);
+       return wim_resource_spec_to_data(&rspec, buf_ret);
+}
+
 struct extract_ctx {
        SHA_CTX sha_ctx;
        consume_data_callback_t extract_chunk;
@@ -907,7 +918,7 @@ extract_wim_resource(const struct wim_lookup_table_entry *lte,
                     void *extract_chunk_arg)
 {
        int ret;
-       if (size == wim_resource_size(lte)) {
+       if (size == lte->size) {
                /* Do SHA1 */
                struct extract_ctx ctx;
                ctx.extract_chunk = extract_chunk;
@@ -915,7 +926,7 @@ extract_wim_resource(const struct wim_lookup_table_entry *lte,
                sha1_init(&ctx.sha_ctx);
                ret = read_resource_prefix(lte, size,
                                           extract_chunk_sha1_wrapper,
-                                          wim_resource_chunk_size(lte),
+                                          lte_cchunk_size(lte),
                                           &ctx, 0);
                if (ret == 0) {
                        u8 hash[SHA1_HASH_SIZE];
@@ -934,7 +945,7 @@ extract_wim_resource(const struct wim_lookup_table_entry *lte,
        } else {
                /* Don't do SHA1 */
                ret = read_resource_prefix(lte, size, extract_chunk,
-                                          wim_resource_chunk_size(lte),
+                                          lte_cchunk_size(lte),
                                           extract_chunk_arg, 0);
        }
        return ret;
@@ -976,8 +987,8 @@ sha1_resource(struct wim_lookup_table_entry *lte)
        SHA_CTX sha_ctx;
 
        sha1_init(&sha_ctx);
-       ret = read_resource_prefix(lte, wim_resource_size(lte),
-                                  sha1_chunk, wim_resource_chunk_size(lte),
+       ret = read_resource_prefix(lte, lte->size,
+                                  sha1_chunk, lte_cchunk_size(lte),
                                   &sha_ctx, 0);
        if (ret == 0)
                sha1_final(lte->hash, &sha_ctx);
@@ -985,61 +996,87 @@ sha1_resource(struct wim_lookup_table_entry *lte)
        return ret;
 }
 
-/* Translates a WIM resource entry from the on-disk format into an in-memory
+/* Convert a WIM resource header to a stand-alone resource specification.  */
+void
+wim_res_hdr_to_spec(const struct wim_reshdr *reshdr, WIMStruct *wim,
+                   struct wim_resource_spec *spec)
+{
+       spec->wim = wim;
+       spec->offset_in_wim = reshdr->offset_in_wim;
+       spec->size_in_wim = reshdr->size_in_wim;
+       spec->uncompressed_size = reshdr->uncompressed_size;
+       INIT_LIST_HEAD(&spec->lte_list);
+       spec->flags = reshdr->flags;
+       spec->is_pipable = wim_is_pipable(wim);
+       if (spec->flags & WIM_RESHDR_FLAG_COMPRESSED) {
+               spec->ctype = wim->compression_type;
+               spec->cchunk_size = wim->chunk_size;
+       } else {
+               spec->ctype = WIMLIB_COMPRESSION_TYPE_NONE;
+               spec->cchunk_size = 0;
+       }
+}
+
+/* Convert a stand-alone resource specification to a WIM resource header.  */
+void
+wim_res_spec_to_hdr(const struct wim_resource_spec *rspec,
+                   struct wim_reshdr *reshdr)
+{
+       reshdr->offset_in_wim     = rspec->offset_in_wim;
+       reshdr->size_in_wim       = rspec->size_in_wim;
+       reshdr->flags             = rspec->flags;
+       reshdr->uncompressed_size = rspec->uncompressed_size;
+}
+
+/* Translates a WIM resource header from the on-disk format into an in-memory
  * format.  */
 void
-get_resource_entry(const struct resource_entry_disk *disk_entry,
-                  struct resource_entry *entry)
+get_wim_reshdr(const struct wim_reshdr_disk *disk_reshdr,
+              struct wim_reshdr *reshdr)
 {
-       /* Note: disk_entry may not be 8 byte aligned--- in that case, the
+       /* Note: disk_reshdr may not be 8 byte aligned--- in that case, the
         * offset and original_size members will be unaligned.  (This is okay
-        * since `struct resource_entry_disk' is declared as packed.)  */
-
-       /* Read the size and flags into a bitfield portably... */
-       entry->size = (((u64)disk_entry->size[0] <<  0) |
-                      ((u64)disk_entry->size[1] <<  8) |
-                      ((u64)disk_entry->size[2] << 16) |
-                      ((u64)disk_entry->size[3] << 24) |
-                      ((u64)disk_entry->size[4] << 32) |
-                      ((u64)disk_entry->size[5] << 40) |
-                      ((u64)disk_entry->size[6] << 48));
-       entry->flags = disk_entry->flags;
-       entry->offset = le64_to_cpu(disk_entry->offset);
-       entry->original_size = le64_to_cpu(disk_entry->original_size);
-
-       /* 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... */
-       if (entry->offset & 0xc000000000000000ULL) {
-               WARNING("Truncating offset in resource entry");
-               entry->offset &= 0x3fffffffffffffffULL;
+        * since `struct resource_reshdr_disk' is declared as packed.)  */
+
+       reshdr->offset_in_wim = le64_to_cpu(disk_reshdr->offset_in_wim);
+       reshdr->size_in_wim = (((u64)disk_reshdr->size_in_wim[0] <<  0) |
+                             ((u64)disk_reshdr->size_in_wim[1] <<  8) |
+                             ((u64)disk_reshdr->size_in_wim[2] << 16) |
+                             ((u64)disk_reshdr->size_in_wim[3] << 24) |
+                             ((u64)disk_reshdr->size_in_wim[4] << 32) |
+                             ((u64)disk_reshdr->size_in_wim[5] << 40) |
+                             ((u64)disk_reshdr->size_in_wim[6] << 48));
+       reshdr->uncompressed_size = le64_to_cpu(disk_reshdr->uncompressed_size);
+       reshdr->flags = disk_reshdr->flags;
+
+       /* Truncate numbers to 62 bits to avoid possible overflows.  */
+       if (reshdr->offset_in_wim & 0xc000000000000000ULL) {
+               WARNING("Truncating offset in resource reshdr");
+               reshdr->offset_in_wim &= 0x3fffffffffffffffULL;
        }
-       if (entry->original_size & 0xc000000000000000ULL) {
-               WARNING("Truncating original_size in resource entry");
-               entry->original_size &= 0x3fffffffffffffffULL;
+       if (reshdr->uncompressed_size & 0xc000000000000000ULL) {
+               WARNING("Truncating original_size in resource reshdr");
+               reshdr->uncompressed_size &= 0x3fffffffffffffffULL;
        }
 }
 
-/* Translates a WIM resource entry from an in-memory format into the on-disk
- * format. */
+/* Translates a WIM resource header from an in-memory format into the on-disk
+ * format.  */
 void
-put_resource_entry(const struct resource_entry *entry,
-                  struct resource_entry_disk *disk_entry)
+put_wim_reshdr(const struct wim_reshdr *reshdr,
+              struct wim_reshdr_disk *disk_reshdr)
 {
-       /* Note: disk_entry may not be 8 byte aligned--- in that case, the
+       /* Note: disk_reshdr may not be 8 byte aligned--- in that case, the
         * offset and original_size members will be unaligned.  (This is okay
-        * since `struct resource_entry_disk' is declared as packed.)  */
-       u64 size = entry->size;
-
-       disk_entry->size[0] = size >>  0;
-       disk_entry->size[1] = size >>  8;
-       disk_entry->size[2] = size >> 16;
-       disk_entry->size[3] = size >> 24;
-       disk_entry->size[4] = size >> 32;
-       disk_entry->size[5] = size >> 40;
-       disk_entry->size[6] = size >> 48;
-       disk_entry->flags = entry->flags;
-       disk_entry->offset = cpu_to_le64(entry->offset);
-       disk_entry->original_size = cpu_to_le64(entry->original_size);
+        * since `struct resource_reshdr_disk' is declared as packed.)  */
+       disk_reshdr->size_in_wim[0] = reshdr->size_in_wim  >>  0;
+       disk_reshdr->size_in_wim[1] = reshdr->size_in_wim  >>  8;
+       disk_reshdr->size_in_wim[2] = reshdr->size_in_wim  >> 16;
+       disk_reshdr->size_in_wim[3] = reshdr->size_in_wim  >> 24;
+       disk_reshdr->size_in_wim[4] = reshdr->size_in_wim  >> 32;
+       disk_reshdr->size_in_wim[5] = reshdr->size_in_wim  >> 40;
+       disk_reshdr->size_in_wim[6] = reshdr->size_in_wim  >> 48;
+       disk_reshdr->flags = reshdr->flags;
+       disk_reshdr->offset_in_wim = cpu_to_le64(reshdr->offset_in_wim);
+       disk_reshdr->uncompressed_size = cpu_to_le64(reshdr->uncompressed_size);
 }
index dd4ba27874603ea83addeca310149b83c31435aa..167105eb47a68ec982741158624deb5956c92480 100644 (file)
@@ -148,7 +148,8 @@ add_stream_to_swm(struct wim_lookup_table_entry *lte, void *_swm_info)
        struct swm_info *swm_info = _swm_info;
        u64 stream_size;
 
-       stream_size = lte->resource_entry.size;
+       /* TODO */
+       stream_size = lte->rspec->size_in_wim;
 
        /* - Start first part if no parts have been started so far;
         * - Start next part if adding this stream exceeds maximum part size,
@@ -158,7 +159,7 @@ add_stream_to_swm(struct wim_lookup_table_entry *lte, void *_swm_info)
        if (swm_info->num_parts == 0 ||
            ((swm_info->parts[swm_info->num_parts - 1].size +
                        stream_size >= swm_info->max_part_size)
-            && !((lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA) ||
+            && !((lte->flags & WIM_RESHDR_FLAG_METADATA) ||
                   swm_info->parts[swm_info->num_parts - 1].size == 0)))
        {
                if (swm_info->num_parts == swm_info->num_alloc_parts) {
@@ -182,7 +183,7 @@ add_stream_to_swm(struct wim_lookup_table_entry *lte, void *_swm_info)
                swm_info->parts[swm_info->num_parts - 1].size = 0;
        }
        swm_info->parts[swm_info->num_parts - 1].size += stream_size;
-       if (!(lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA)) {
+       if (!(lte->flags & WIM_RESHDR_FLAG_METADATA)) {
                list_add_tail(&lte->write_streams_list,
                              &swm_info->parts[swm_info->num_parts - 1].stream_list);
        }
index 86be081ff006cf220ec2850512c8f032deddc00d..ca0f485c4177582957a81e9e7ede0acd6b60bff9 100644 (file)
@@ -122,7 +122,7 @@ unix_extract_unnamed_stream(file_spec_t file,
        if (raw_fd < 0)
                return WIMLIB_ERR_OPEN;
        filedes_init(&fd, raw_fd);
-       ret = extract_wim_resource_to_fd(lte, &fd, wim_resource_size(lte));
+       ret = extract_wim_resource_to_fd(lte, &fd, lte->size);
        if (filedes_close(&fd) && !ret)
                ret = WIMLIB_ERR_WRITE;
        return ret;
index ff9a6ac00179e977ebd8cadf8dc013717c86957b..1d116d4b09ac77a430640858e9334a5ef2b53c1d 100644 (file)
@@ -64,7 +64,7 @@ unix_capture_regular_file(const char *path,
                }
                lte->file_on_disk = file_on_disk;
                lte->resource_location = RESOURCE_IN_FILE_ON_DISK;
-               lte->resource_entry.original_size = size;
+               lte->size = size;
                lookup_table_insert_unhashed(lookup_table, lte, inode, 0);
                inode->i_lte = lte;
        }
index c0825687f7f3f38ab4141090dce344f1e5fc1715..a62be39e05709c8f8a66f30d3461b1ac8e39700c 100644 (file)
--- a/src/wim.c
+++ b/src/wim.c
@@ -138,6 +138,10 @@ wim_chunk_size_valid(u32 chunk_size, int ctype)
                 * 2^15 = 32768 is the default value used for compatibility, but
                 * wimlib can actually use up to 2^26.  */
                return order >= 15 && order <= 26;
+
+       case WIMLIB_COMPRESSION_TYPE_LZMS:
+               /* TODO */
+               return 131072;
        }
        return false;
 }
@@ -371,7 +375,7 @@ wimlib_get_wim_info(WIMStruct *wim, struct wimlib_wim_info *info)
        memcpy(info->guid, wim->hdr.guid, WIMLIB_GUID_LEN);
        info->image_count = wim->hdr.image_count;
        info->boot_index = wim->hdr.boot_idx;
-       info->wim_version = WIM_VERSION;
+       info->wim_version = wim->hdr.wim_version;
        info->chunk_size = wim->hdr.chunk_size;
        info->part_number = wim->hdr.part_number;
        info->total_parts = wim->hdr.total_parts;
@@ -535,7 +539,6 @@ begin_read(WIMStruct *wim, const void *wim_filename_or_fd,
                wim->in_fd.is_pipe = 1;
        } else {
                wimfile = wim_filename_or_fd;
-               DEBUG("Reading the WIM file `%"TS"'", wimfile);
                ret = do_open_wim(wimfile, &wim->in_fd);
                if (ret)
                        return ret;
@@ -562,7 +565,7 @@ begin_read(WIMStruct *wim, const void *wim_filename_or_fd,
                }
        }
 
-       ret = read_wim_header(wim->filename, &wim->in_fd, &wim->hdr);
+       ret = read_wim_header(wim, &wim->hdr);
        if (ret)
                return ret;
 
@@ -596,17 +599,17 @@ begin_read(WIMStruct *wim, const void *wim_filename_or_fd,
        /* Check and cache the compression type */
        if (wim->hdr.flags & WIM_HDR_FLAG_COMPRESSION) {
                if (wim->hdr.flags & WIM_HDR_FLAG_COMPRESS_LZX) {
-                       if (wim->hdr.flags & WIM_HDR_FLAG_COMPRESS_XPRESS) {
-                               ERROR("Multiple compression flags are set in \"%"TS"\"",
-                                     wimfile);
-                               return WIMLIB_ERR_INVALID_COMPRESSION_TYPE;
-                       }
                        wim->compression_type = WIMLIB_COMPRESSION_TYPE_LZX;
                } else if (wim->hdr.flags & WIM_HDR_FLAG_COMPRESS_XPRESS) {
                        wim->compression_type = WIMLIB_COMPRESSION_TYPE_XPRESS;
+       #if 0
+               /* TODO */
+               } else if (wim->hdr.flags & WIM_HDR_FLAG_COMPRESS_LZMS) {
+                       wim->compression_type = WIMLIB_COMPRESSION_TYPE_LZMS;
+       #endif
                } else {
                        ERROR("The compression flag is set on \"%"TS"\", but "
-                             "neither the XPRESS nor LZX flag is set",
+                             "a flag for a recognized format is not",
                              wimfile);
                        return WIMLIB_ERR_INVALID_COMPRESSION_TYPE;
                }
@@ -677,6 +680,11 @@ open_wim_as_WIMStruct(const void *wim_filename_or_fd, int open_flags,
        WIMStruct *wim;
        int ret;
 
+       if (open_flags & WIMLIB_OPEN_FLAG_FROM_PIPE)
+               DEBUG("Opening pipable WIM from file descriptor %d.", *(const int*)wim_filename_or_fd);
+       else
+               DEBUG("Opening WIM file \"%"TS"\"", (const tchar*)wim_filename_or_fd);
+
        wimlib_global_init(WIMLIB_INIT_FLAG_ASSUME_UTF8);
 
        if (wim_ret == NULL)
@@ -692,6 +700,7 @@ open_wim_as_WIMStruct(const void *wim_filename_or_fd, int open_flags,
                return ret;
        }
 
+       DEBUG("Successfully opened WIM and created WIMStruct.");
        *wim_ret = wim;
        return 0;
 }
index 557572330946b99118b61d54f12be6fada7b613d..1a4adf5c3736622ae8bc623e16f4203f84afc80d 100644 (file)
@@ -195,8 +195,7 @@ win32_extract_stream(const wchar_t *path, const wchar_t *stream_name,
        ret = 0;
        if (!lte)
                goto out_close_handle;
-       ret = extract_wim_resource(lte, wim_resource_size(lte),
-                                  win32_extract_wim_chunk, h);
+       ret = extract_wim_resource(lte, lte->size, win32_extract_wim_chunk, h);
 out_close_handle:
        if (!CloseHandle(h))
                goto error;
@@ -239,7 +238,7 @@ win32_encrypted_import_cb(unsigned char *data, void *_import_ctx,
        unsigned long len = *len_p;
        const struct wim_lookup_table_entry *lte = import_ctx->lte;
 
-       len = min(len, wim_resource_size(lte) - import_ctx->offset);
+       len = min(len, lte->size - import_ctx->offset);
 
        if (read_partial_wim_resource_into_buf(lte, len, import_ctx->offset, data))
                return ERROR_READ_FAULT;
index ce301063612327662f3936e0e6b82ee227320734..80a3b096ffaabef3032d78ce903e9fbdaff0bdd1 100644 (file)
@@ -74,8 +74,8 @@ static bool
 can_raw_copy(const struct wim_lookup_table_entry *lte,
             int write_resource_flags, int out_ctype, u32 out_chunk_size)
 {
-       return (out_ctype == wim_resource_compression_type(lte)
-               && out_chunk_size == wim_resource_chunk_size(lte)
+       return (out_ctype == lte_ctype(lte)
+               && out_chunk_size == lte_cchunk_size(lte)
                && out_ctype != WIMLIB_COMPRESSION_TYPE_NONE);
 }
 
@@ -150,7 +150,7 @@ begin_wim_resource_chunk_tab(const struct wim_lookup_table_entry *lte,
        struct chunk_table *chunk_tab;
        int ret;
 
-       size = wim_resource_size(lte);
+       size = lte->size;
        num_chunks = DIV_ROUND_UP(size, out_chunk_size);
        bytes_per_chunk_entry = (size > (1ULL << 32)) ? 8 : 4;
        alloc_size = sizeof(struct chunk_table) + num_chunks * sizeof(u64);
@@ -245,7 +245,7 @@ write_pwm_stream_header(const struct wim_lookup_table_entry *lte,
        int ret;
 
        stream_hdr.magic = PWM_STREAM_MAGIC;
-       stream_hdr.uncompressed_size = cpu_to_le64(lte->resource_entry.original_size);
+       stream_hdr.uncompressed_size = cpu_to_le64(lte->size);
        if (additional_reshdr_flags & PWM_RESHDR_FLAG_UNHASHED) {
                zero_out_hash(stream_hdr.hash);
        } else {
@@ -253,7 +253,7 @@ write_pwm_stream_header(const struct wim_lookup_table_entry *lte,
                copy_hash(stream_hdr.hash, lte->hash);
        }
 
-       reshdr_flags = lte->resource_entry.flags & ~WIM_RESHDR_FLAG_COMPRESSED;
+       reshdr_flags = lte->flags & ~WIM_RESHDR_FLAG_COMPRESSED;
        reshdr_flags |= additional_reshdr_flags;
        stream_hdr.flags = cpu_to_le32(reshdr_flags);
        ret = full_write(out_fd, &stream_hdr, sizeof(stream_hdr));
@@ -397,7 +397,7 @@ error:
  * @out_chunk_size:
  *     Compressed chunk size to use.
  *
- * @out_res_entry:
+ * @out_reshdr:
  *     On success, this is filled in with the offset, flags, compressed size,
  *     and uncompressed size of the resource in the output WIM.
  *
@@ -421,7 +421,7 @@ static int
 write_wim_resource(struct wim_lookup_table_entry *lte,
                   struct filedes *out_fd, int out_ctype,
                   u32 out_chunk_size,
-                  struct resource_entry *out_res_entry,
+                  struct wim_reshdr *out_reshdr,
                   int resource_flags,
                   struct wimlib_lzx_context **comp_ctx)
 {
@@ -450,20 +450,20 @@ write_wim_resource(struct wim_lookup_table_entry *lte,
                 * needs to be requested so that the written resource can be
                 * appropriately formatted.  However, in neither case is any
                 * actual decompression needed.  */
-               if (lte->is_pipable == !!(resource_flags &
-                                         WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE))
+               if (lte->rspec->is_pipable == !!(resource_flags &
+                                                WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE))
                {
                        resource_flags |= WIMLIB_READ_RESOURCE_FLAG_RAW_FULL;
-                       read_size = lte->resource_entry.size;
+                       read_size = lte->rspec->size_in_wim;
                } else {
                        resource_flags |= WIMLIB_READ_RESOURCE_FLAG_RAW_CHUNKS;
-                       read_size = lte->resource_entry.original_size;
+                       read_size = lte->size;
                }
                write_ctx.doing_sha = false;
        } else {
                write_ctx.doing_sha = true;
                sha1_init(&write_ctx.sha_ctx);
-               read_size = lte->resource_entry.original_size;
+               read_size = lte->size;
        }
 
        /* Set the output compression mode and initialize chunk table if needed.
@@ -513,7 +513,7 @@ write_wim_resource(struct wim_lookup_table_entry *lte,
        write_ctx.resource_flags = resource_flags;
 try_write_again:
        if (write_ctx.out_ctype == WIMLIB_COMPRESSION_TYPE_NONE)
-               in_chunk_size = wim_resource_chunk_size(lte);
+               in_chunk_size = lte_cchunk_size(lte);
        else
                in_chunk_size = out_chunk_size;
        ret = read_resource_prefix(lte, read_size,
@@ -540,27 +540,27 @@ try_write_again:
                        goto out_free_chunk_tab;
        }
 
-       /* Fill in out_res_entry with information about the newly written
+       /* Fill in out_reshdr with information about the newly written
         * resource.  */
-       out_res_entry->size          = out_fd->offset - res_start_offset;
-       out_res_entry->flags         = lte->resource_entry.flags;
+       out_reshdr->size_in_wim   = out_fd->offset - res_start_offset;
+       out_reshdr->flags         = lte->flags;
        if (out_ctype == WIMLIB_COMPRESSION_TYPE_NONE)
-               out_res_entry->flags &= ~WIM_RESHDR_FLAG_COMPRESSED;
+               out_reshdr->flags &= ~WIM_RESHDR_FLAG_COMPRESSED;
        else
-               out_res_entry->flags |= WIM_RESHDR_FLAG_COMPRESSED;
-       out_res_entry->offset        = res_start_offset;
-       out_res_entry->original_size = wim_resource_size(lte);
+               out_reshdr->flags |= WIM_RESHDR_FLAG_COMPRESSED;
+       out_reshdr->offset_in_wim  = res_start_offset;
+       out_reshdr->uncompressed_size = lte->size;
 
        /* Check for resources compressed to greater than their original size
         * and write them uncompressed instead.  (But never do this if writing
         * to a pipe, and don't bother if we did a raw copy.)  */
-       if (out_res_entry->size > out_res_entry->original_size &&
+       if (out_reshdr->size_in_wim > out_reshdr->uncompressed_size &&
            !(resource_flags & (WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE |
                                WIMLIB_READ_RESOURCE_FLAG_RAW)))
        {
                DEBUG("Compressed %"PRIu64" => %"PRIu64" bytes; "
                      "writing uncompressed instead",
-                     out_res_entry->original_size, out_res_entry->size);
+                     out_reshdr->uncompressed_size, out_reshdr->size_in_wim);
                ret = seek_and_truncate(out_fd, res_start_offset);
                if (ret)
                        goto out_free_chunk_tab;
@@ -574,18 +574,18 @@ try_write_again:
        if (resource_flags & WIMLIB_READ_RESOURCE_FLAG_RAW) {
                DEBUG("Copied raw compressed data "
                      "(%"PRIu64" => %"PRIu64" bytes @ +%"PRIu64", flags=0x%02x)",
-                     out_res_entry->original_size, out_res_entry->size,
-                     out_res_entry->offset, out_res_entry->flags);
+                     out_reshdr->uncompressed_size, out_reshdr->size_in_wim,
+                     out_reshdr->offset_in_wim, out_reshdr->flags);
        } else if (out_ctype != WIMLIB_COMPRESSION_TYPE_NONE) {
                DEBUG("Wrote compressed resource "
                      "(%"PRIu64" => %"PRIu64" bytes @ +%"PRIu64", flags=0x%02x)",
-                     out_res_entry->original_size, out_res_entry->size,
-                     out_res_entry->offset, out_res_entry->flags);
+                     out_reshdr->uncompressed_size, out_reshdr->size_in_wim,
+                     out_reshdr->offset_in_wim, out_reshdr->flags);
        } else {
                DEBUG("Wrote uncompressed resource "
                      "(%"PRIu64" bytes @ +%"PRIu64", flags=0x%02x)",
-                     out_res_entry->original_size,
-                     out_res_entry->offset, out_res_entry->flags);
+                     out_reshdr->uncompressed_size,
+                     out_reshdr->offset_in_wim, out_reshdr->flags);
        }
        ret = 0;
 out_free_chunk_tab:
@@ -602,7 +602,7 @@ write_wim_resource_from_buffer(const void *buf, size_t buf_size,
                               int reshdr_flags, struct filedes *out_fd,
                               int out_ctype,
                               u32 out_chunk_size,
-                              struct resource_entry *out_res_entry,
+                              struct wim_reshdr *out_reshdr,
                               u8 *hash_ret, int write_resource_flags,
                               struct wimlib_lzx_context **comp_ctx)
 {
@@ -616,10 +616,10 @@ write_wim_resource_from_buffer(const void *buf, size_t buf_size,
        if (lte == NULL)
                return WIMLIB_ERR_NOMEM;
 
-       lte->resource_location            = RESOURCE_IN_ATTACHED_BUFFER;
-       lte->attached_buffer              = (void*)buf;
-       lte->resource_entry.original_size = buf_size;
-       lte->resource_entry.flags         = reshdr_flags;
+       lte->resource_location  = RESOURCE_IN_ATTACHED_BUFFER;
+       lte->attached_buffer    = (void*)buf;
+       lte->size               = buf_size;
+       lte->flags              = reshdr_flags;
 
        if (write_resource_flags & WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE) {
                sha1_buffer(buf, buf_size, lte->hash);
@@ -629,7 +629,7 @@ write_wim_resource_from_buffer(const void *buf, size_t buf_size,
        }
 
        ret = write_wim_resource(lte, out_fd, out_ctype, out_chunk_size,
-                                out_res_entry, write_resource_flags, comp_ctx);
+                                out_reshdr, write_resource_flags, comp_ctx);
        if (ret)
                goto out_free_lte;
        if (hash_ret)
@@ -821,24 +821,24 @@ do_write_streams_progress(struct write_streams_progress_data *progress_data,
        bool new_wim_part;
 
        if (stream_discarded) {
-               progress->write_streams.total_bytes -= wim_resource_size(lte);
+               progress->write_streams.total_bytes -= lte->size;
                if (progress_data->next_progress != ~(uint64_t)0 &&
                    progress_data->next_progress > progress->write_streams.total_bytes)
                {
                        progress_data->next_progress = progress->write_streams.total_bytes;
                }
        } else {
-               progress->write_streams.completed_bytes += wim_resource_size(lte);
+               progress->write_streams.completed_bytes += lte->size;
        }
        new_wim_part = false;
        if (lte->resource_location == RESOURCE_IN_WIM &&
-           lte->wim != progress_data->prev_wim_part)
+           lte->rspec->wim != progress_data->prev_wim_part)
        {
                if (progress_data->prev_wim_part) {
                        new_wim_part = true;
                        progress->write_streams.completed_parts++;
                }
-               progress_data->prev_wim_part = lte->wim;
+               progress_data->prev_wim_part = lte->rspec->wim;
        }
        progress->write_streams.completed_streams++;
        if (progress_data->progress_func
@@ -873,7 +873,7 @@ serial_write_stream(struct wim_lookup_table_entry *lte, void *_ctx)
        return write_wim_resource(lte, ctx->out_fd,
                                  ctx->out_ctype,
                                  ctx->out_chunk_size,
-                                 &lte->output_resource_entry,
+                                 &lte->out_reshdr,
                                  ctx->write_resource_flags,
                                  ctx->comp_ctx);
 }
@@ -929,7 +929,7 @@ do_write_stream_list(struct list_head *stream_list,
                                    lte->filtered) {
                                        DEBUG("Discarding duplicate stream of "
                                              "length %"PRIu64,
-                                             wim_resource_size(lte));
+                                             lte->size);
                                        lte->no_progress = 0;
                                        stream_discarded = true;
                                        goto skip_to_progress;
@@ -1290,12 +1290,12 @@ receive_compressed_chunks(struct main_writer_thread_ctx *ctx)
                         * equal to their original size and write them
                         * uncompressed instead.  (But never do this if writing
                         * to a pipe.)  */
-                       if (res_csize >= wim_resource_size(cur_lte) &&
+                       if (res_csize >= cur_lte->size &&
                            !(ctx->write_resource_flags & WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE))
                        {
                                DEBUG("Compressed %"PRIu64" => %"PRIu64" bytes; "
                                      "writing uncompressed instead",
-                                     wim_resource_size(cur_lte), res_csize);
+                                     cur_lte->size, res_csize);
                                ret = seek_and_truncate(ctx->out_fd, ctx->res_start_offset);
                                if (ret)
                                        return ret;
@@ -1303,31 +1303,31 @@ receive_compressed_chunks(struct main_writer_thread_ctx *ctx)
                                                         ctx->out_fd,
                                                         WIMLIB_COMPRESSION_TYPE_NONE,
                                                         0,
-                                                        &cur_lte->output_resource_entry,
+                                                        &cur_lte->out_reshdr,
                                                         ctx->write_resource_flags,
                                                         ctx->comp_ctx);
                                if (ret)
                                        return ret;
                        } else {
-                               cur_lte->output_resource_entry.size =
+                               cur_lte->out_reshdr.size_in_wim =
                                        res_csize;
 
-                               cur_lte->output_resource_entry.original_size =
-                                       cur_lte->resource_entry.original_size;
+                               cur_lte->out_reshdr.uncompressed_size =
+                                       cur_lte->size;
 
-                               cur_lte->output_resource_entry.offset =
+                               cur_lte->out_reshdr.offset_in_wim =
                                        ctx->res_start_offset;
 
-                               cur_lte->output_resource_entry.flags =
-                                       cur_lte->resource_entry.flags |
+                               cur_lte->out_reshdr.flags =
+                                       cur_lte->flags |
                                                WIM_RESHDR_FLAG_COMPRESSED;
 
                                DEBUG("Wrote compressed resource "
                                      "(%"PRIu64" => %"PRIu64" bytes @ +%"PRIu64", flags=0x%02x)",
-                                     cur_lte->output_resource_entry.original_size,
-                                     cur_lte->output_resource_entry.size,
-                                     cur_lte->output_resource_entry.offset,
-                                     cur_lte->output_resource_entry.flags);
+                                     cur_lte->out_reshdr.uncompressed_size,
+                                     cur_lte->out_reshdr.size_in_wim,
+                                     cur_lte->out_reshdr.offset_in_wim,
+                                     cur_lte->out_reshdr.flags);
                        }
 
                        do_write_streams_progress(ctx->progress_data,
@@ -1462,12 +1462,11 @@ submit_stream_for_compression(struct wim_lookup_table_entry *lte,
         * when @lte is already hashed.  */
        sha1_init(&ctx->next_sha_ctx);
        ctx->next_chunk = 0;
-       ctx->next_num_chunks = DIV_ROUND_UP(wim_resource_size(lte),
-                                           ctx->out_chunk_size);
+       ctx->next_num_chunks = DIV_ROUND_UP(lte->size, ctx->out_chunk_size);
        ctx->next_lte = lte;
        INIT_LIST_HEAD(&lte->msg_list);
        list_add_tail(&lte->being_compressed_list, &ctx->outstanding_streams);
-       ret = read_resource_prefix(lte, wim_resource_size(lte),
+       ret = read_resource_prefix(lte, lte->size,
                                   main_writer_thread_cb,
                                   ctx->out_chunk_size, ctx, 0);
        if (ret)
@@ -1482,7 +1481,7 @@ main_thread_process_next_stream(struct wim_lookup_table_entry *lte, void *_ctx)
        struct main_writer_thread_ctx *ctx = _ctx;
        int ret;
 
-       if (wim_resource_size(lte) < 1000 ||
+       if (lte->size < 1000 ||
            !must_compress_stream(lte, ctx->write_resource_flags,
                                  ctx->out_ctype, ctx->out_chunk_size))
        {
@@ -1754,13 +1753,13 @@ write_stream_list(struct list_head *stream_list,
        prev_wim_part = NULL;
        list_for_each_entry(lte, stream_list, write_streams_list) {
                num_streams++;
-               total_bytes += wim_resource_size(lte);
+               total_bytes += lte->size;
                if (must_compress_stream(lte, write_resource_flags,
                                         out_ctype, out_chunk_size))
-                       total_compression_bytes += wim_resource_size(lte);
+                       total_compression_bytes += lte->size;
                if (lte->resource_location == RESOURCE_IN_WIM) {
-                       if (prev_wim_part != lte->wim) {
-                               prev_wim_part = lte->wim;
+                       if (prev_wim_part != lte->rspec->wim) {
+                               prev_wim_part = lte->rspec->wim;
                                total_parts++;
                        }
                }
@@ -1840,10 +1839,10 @@ stream_size_table_insert(struct wim_lookup_table_entry *lte, void *_tab)
        struct wim_lookup_table_entry *same_size_lte;
        struct hlist_node *tmp;
 
-       pos = hash_u64(wim_resource_size(lte)) % tab->capacity;
+       pos = hash_u64(lte->size) % tab->capacity;
        lte->unique_size = 1;
        hlist_for_each_entry(same_size_lte, tmp, &tab->array[pos], hash_list_2) {
-               if (wim_resource_size(same_size_lte) == wim_resource_size(lte)) {
+               if (same_size_lte->size == lte->size) {
                        lte->unique_size = 0;
                        same_size_lte->unique_size = 0;
                        break;
@@ -1949,7 +1948,6 @@ prepare_logical_stream_list(WIMStruct *wim, int image, bool streams_ok,
                            struct find_streams_ctx *ctx)
 {
        int ret;
-       struct wim_lookup_table_entry *lte;
 
        if (streams_ok && (image == WIMLIB_ALL_IMAGES ||
                           (image == 1 && wim->hdr.image_count == 1)))
@@ -1977,8 +1975,6 @@ prepare_logical_stream_list(WIMStruct *wim, int image, bool streams_ok,
                        return ret;
        }
 
-       list_for_each_entry(lte, &ctx->stream_list, write_streams_list)
-               lte->part_number = wim->hdr.part_number;
        return 0;
 }
 
@@ -1990,10 +1986,10 @@ process_filtered_stream(struct wim_lookup_table_entry *lte, void *_ctx)
 
        /* Calculate and set lte->filtered.  */
        if (lte->resource_location == RESOURCE_IN_WIM) {
-               if (lte->wim == ctx->wim &&
+               if (lte->rspec->wim == ctx->wim &&
                    (ctx->write_flags & WIMLIB_WRITE_FLAG_OVERWRITE))
                        filtered |= FILTERED_SAME_WIM;
-               if (lte->wim != ctx->wim &&
+               if (lte->rspec->wim != ctx->wim &&
                    (ctx->write_flags & WIMLIB_WRITE_FLAG_SKIP_EXTERNAL_WIMS))
                        filtered |= FILTERED_EXTERNAL_WIM;
        }
@@ -2112,10 +2108,8 @@ write_wim_streams(WIMStruct *wim, int image, int write_flags,
                 * use stream list already explicitly provided.  Use existing
                 * reference counts.  */
                stream_list = stream_list_override;
-               list_for_each_entry(lte, stream_list, write_streams_list) {
+               list_for_each_entry(lte, stream_list, write_streams_list)
                        lte->out_refcnt = (lte->refcnt ? lte->refcnt : 1);
-                       lte->part_number = wim->hdr.part_number;
-               }
        }
 
        return write_stream_list(stream_list,
@@ -2174,8 +2168,8 @@ write_wim_metadata_resources(WIMStruct *wim, int image, int write_flags,
                } else if (write_flags & WIMLIB_WRITE_FLAG_OVERWRITE) {
                        DEBUG("Image %u was not modified; re-using existing "
                              "metadata resource.", i);
-                       copy_resource_entry(&imd->metadata_lte->output_resource_entry,
-                                           &imd->metadata_lte->resource_entry);
+                       wim_res_spec_to_hdr(imd->metadata_lte->rspec,
+                                           &imd->metadata_lte->out_reshdr);
                        ret = 0;
                } else {
                        DEBUG("Image %u was not modified; copying existing "
@@ -2184,7 +2178,7 @@ write_wim_metadata_resources(WIMStruct *wim, int image, int write_flags,
                                                 &wim->out_fd,
                                                 wim->out_compression_type,
                                                 wim->out_chunk_size,
-                                                &imd->metadata_lte->output_resource_entry,
+                                                &imd->metadata_lte->out_reshdr,
                                                 write_resource_flags,
                                                 &wim->lzx_context);
                }
@@ -2294,19 +2288,19 @@ finish_write(WIMStruct *wim, int image, int write_flags,
         * it should be a copy of the resource entry for the image that is
         * marked as bootable.  This is not well documented...  */
        if (wim->hdr.boot_idx == 0) {
-               zero_resource_entry(&wim->hdr.boot_metadata_res_entry);
+               zero_reshdr(&wim->hdr.boot_metadata_reshdr);
        } else {
-               copy_resource_entry(&wim->hdr.boot_metadata_res_entry,
+               copy_reshdr(&wim->hdr.boot_metadata_reshdr,
                            &wim->image_metadata[wim->hdr.boot_idx- 1
-                                       ]->metadata_lte->output_resource_entry);
+                                       ]->metadata_lte->out_reshdr);
        }
 
        /* Write lookup table.  (Save old position first.)  */
-       old_lookup_table_end = wim->hdr.lookup_table_res_entry.offset +
-                              wim->hdr.lookup_table_res_entry.size;
+       old_lookup_table_end = wim->hdr.lookup_table_reshdr.offset_in_wim +
+                              wim->hdr.lookup_table_reshdr.size_in_wim;
        if (!(write_flags & WIMLIB_WRITE_FLAG_NO_LOOKUP_TABLE)) {
                ret = write_wim_lookup_table(wim, image, write_flags,
-                                            &wim->hdr.lookup_table_res_entry,
+                                            &wim->hdr.lookup_table_reshdr,
                                             stream_list_override);
                if (ret)
                        return ret;
@@ -2317,7 +2311,7 @@ finish_write(WIMStruct *wim, int image, int write_flags,
        if (write_flags & WIMLIB_WRITE_FLAG_USE_EXISTING_TOTALBYTES)
                xml_totalbytes = WIM_TOTALBYTES_USE_EXISTING;
        ret = write_wim_xml_data(wim, image, xml_totalbytes,
-                                &wim->hdr.xml_res_entry,
+                                &wim->hdr.xml_data_reshdr,
                                 write_resource_flags);
        if (ret)
                return ret;
@@ -2327,7 +2321,7 @@ finish_write(WIMStruct *wim, int image, int write_flags,
                if (write_flags & WIMLIB_WRITE_FLAG_CHECKPOINT_AFTER_XML) {
                        struct wim_header checkpoint_hdr;
                        memcpy(&checkpoint_hdr, &wim->hdr, sizeof(struct wim_header));
-                       zero_resource_entry(&checkpoint_hdr.integrity);
+                       zero_reshdr(&checkpoint_hdr.integrity_table_reshdr);
                        checkpoint_hdr.flags |= WIM_HDR_FLAG_WRITE_IN_PROGRESS;
                        ret = write_wim_header_at_offset(&checkpoint_hdr,
                                                         &wim->out_fd, 0);
@@ -2338,8 +2332,8 @@ finish_write(WIMStruct *wim, int image, int write_flags,
                if (!(write_flags & WIMLIB_WRITE_FLAG_REUSE_INTEGRITY_TABLE))
                        old_lookup_table_end = 0;
 
-               new_lookup_table_end = wim->hdr.lookup_table_res_entry.offset +
-                                      wim->hdr.lookup_table_res_entry.size;
+               new_lookup_table_end = wim->hdr.lookup_table_reshdr.offset_in_wim +
+                                      wim->hdr.lookup_table_reshdr.size_in_wim;
 
                ret = write_integrity_table(wim,
                                            new_lookup_table_end,
@@ -2349,7 +2343,7 @@ finish_write(WIMStruct *wim, int image, int write_flags,
                        return ret;
        } else {
                /* No integrity table.  */
-               zero_resource_entry(&wim->hdr.integrity);
+               zero_reshdr(&wim->hdr.integrity_table_reshdr);
        }
 
        /* Now that all information in the WIM header has been determined, the
@@ -2497,7 +2491,7 @@ write_pipable_wim(WIMStruct *wim, int image, int write_flags,
                  struct list_head *stream_list_override)
 {
        int ret;
-       struct resource_entry xml_res_entry;
+       struct wim_reshdr xml_reshdr;
 
        WARNING("Creating a pipable WIM, which will "
                "be incompatible\n"
@@ -2520,7 +2514,7 @@ write_pipable_wim(WIMStruct *wim, int image, int write_flags,
 
        /* Write extra copy of the XML data.  */
        ret = write_wim_xml_data(wim, image, WIM_TOTALBYTES_OMIT,
-                                &xml_res_entry,
+                                &xml_reshdr,
                                 WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE);
        if (ret)
                return ret;
@@ -2682,10 +2676,10 @@ write_wim_part(WIMStruct *wim,
                randomize_byte_array(wim->hdr.guid, WIMLIB_GUID_LEN);
 
        /* Clear references to resources that have not been written yet.  */
-       zero_resource_entry(&wim->hdr.lookup_table_res_entry);
-       zero_resource_entry(&wim->hdr.xml_res_entry);
-       zero_resource_entry(&wim->hdr.boot_metadata_res_entry);
-       zero_resource_entry(&wim->hdr.integrity);
+       zero_reshdr(&wim->hdr.lookup_table_reshdr);
+       zero_reshdr(&wim->hdr.xml_data_reshdr);
+       zero_reshdr(&wim->hdr.boot_metadata_reshdr);
+       zero_reshdr(&wim->hdr.integrity_table_reshdr);
 
        /* Set image count and boot index correctly for single image writes.  */
        if (image != WIMLIB_ALL_IMAGES) {
@@ -2838,8 +2832,8 @@ check_resource_offset(struct wim_lookup_table_entry *lte, void *_wim)
        const WIMStruct *wim = _wim;
        off_t end_offset = *(const off_t*)wim->private;
 
-       if (lte->resource_location == RESOURCE_IN_WIM && lte->wim == wim &&
-           lte->resource_entry.offset + lte->resource_entry.size > end_offset)
+       if (lte->resource_location == RESOURCE_IN_WIM && lte->rspec->wim == wim &&
+           lte->rspec->offset_in_wim + lte->rspec->size_in_wim > end_offset)
                return WIMLIB_ERR_RESOURCE_ORDER;
        return 0;
 }
@@ -2950,11 +2944,12 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags,
         * data, and that there are no stream resources, metadata resources, or
         * lookup tables after the XML data.  Otherwise, these data would be
         * overwritten. */
-       old_xml_begin = wim->hdr.xml_res_entry.offset;
-       old_xml_end = old_xml_begin + wim->hdr.xml_res_entry.size;
-       old_lookup_table_end = wim->hdr.lookup_table_res_entry.offset +
-                              wim->hdr.lookup_table_res_entry.size;
-       if (wim->hdr.integrity.offset != 0 && wim->hdr.integrity.offset < old_xml_end) {
+       old_xml_begin = wim->hdr.xml_data_reshdr.offset_in_wim;
+       old_xml_end = old_xml_begin + wim->hdr.xml_data_reshdr.size_in_wim;
+       old_lookup_table_end = wim->hdr.lookup_table_reshdr.offset_in_wim +
+                              wim->hdr.lookup_table_reshdr.size_in_wim;
+       if (wim->hdr.integrity_table_reshdr.offset_in_wim != 0 &&
+           wim->hdr.integrity_table_reshdr.offset_in_wim < old_xml_end) {
                WARNING("Didn't expect the integrity table to be before the XML data");
                return WIMLIB_ERR_RESOURCE_ORDER;
        }
@@ -2979,10 +2974,11 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags,
                old_wim_end = old_lookup_table_end;
                write_flags |= WIMLIB_WRITE_FLAG_NO_LOOKUP_TABLE |
                               WIMLIB_WRITE_FLAG_CHECKPOINT_AFTER_XML;
-       } else if (wim->hdr.integrity.offset) {
+       } else if (wim->hdr.integrity_table_reshdr.offset_in_wim != 0) {
                /* Old WIM has an integrity table; begin writing new streams
                 * after it. */
-               old_wim_end = wim->hdr.integrity.offset + wim->hdr.integrity.size;
+               old_wim_end = wim->hdr.integrity_table_reshdr.offset_in_wim +
+                             wim->hdr.integrity_table_reshdr.size_in_wim;
        } else {
                /* No existing integrity table; begin writing new streams after
                 * the old XML data. */
index cd335e07d65fa4a72a09223699484b382c7aa8ce..4a8bda9a56d0c5a99ce76f7cb81541bab1beea94 100644 (file)
--- a/src/xml.c
+++ b/src/xml.c
@@ -36,6 +36,7 @@
 #include "wimlib/resource.h"
 #include "wimlib/timestamp.h"
 #include "wimlib/xml.h"
+#include "wimlib/write.h"
 
 #include <libxml/encoding.h>
 #include <libxml/parser.h>
@@ -1153,9 +1154,9 @@ calculate_dentry_statistics(struct wim_dentry *dentry, void *arg)
         */
        lte = inode_unnamed_lte(inode, info->lookup_table);
        if (lte) {
-               info->total_bytes += wim_resource_size(lte);
+               info->total_bytes += lte->size;
                if (!dentry_is_first_in_inode(dentry))
-                       info->hard_link_bytes += wim_resource_size(lte);
+                       info->hard_link_bytes += lte->size;
        }
 
        if (inode->i_nlink >= 2 && dentry_is_first_in_inode(dentry)) {
@@ -1164,7 +1165,7 @@ calculate_dentry_statistics(struct wim_dentry *dentry, void *arg)
                                lte = inode_stream_lte(inode, i + 1, info->lookup_table);
                                if (lte) {
                                        info->hard_link_bytes += inode->i_nlink *
-                                                                wim_resource_size(lte);
+                                                                lte->size;
                                }
                        }
                }
@@ -1311,23 +1312,18 @@ int
 read_wim_xml_data(WIMStruct *wim)
 {
        void *buf;
+       size_t bufsize;
        u8 *xml_data;
        xmlDoc *doc;
        xmlNode *root;
        int ret;
-       const struct resource_entry *res_entry;
-
-       res_entry = &wim->hdr.xml_res_entry;
-
-       DEBUG("Reading XML data: %"PRIu64" bytes at offset %"PRIu64"",
-             (u64)res_entry->size, res_entry->offset);
 
-       ret = res_entry_to_data(res_entry, wim, &buf);
+       ret = wimlib_get_xml_data(wim, &buf, &bufsize);
        if (ret)
                goto out;
        xml_data = buf;
 
-       doc = xmlReadMemory((const char *)xml_data, res_entry->original_size,
+       doc = xmlReadMemory((const char *)xml_data, bufsize,
                            NULL, "UTF-16LE", 0);
        if (!doc) {
                ERROR("Failed to parse XML data");
@@ -1500,7 +1496,7 @@ out_write_error:
 /* Writes the XML data to a WIM file.  */
 int
 write_wim_xml_data(WIMStruct *wim, int image, u64 total_bytes,
-                  struct resource_entry *out_res_entry,
+                  struct wim_reshdr *out_reshdr,
                   int write_resource_flags)
 {
        int ret;
@@ -1523,7 +1519,7 @@ write_wim_xml_data(WIMStruct *wim, int image, u64 total_bytes,
                                             &wim->out_fd,
                                             WIMLIB_COMPRESSION_TYPE_NONE,
                                             0,
-                                            out_res_entry,
+                                            out_reshdr,
                                             NULL,
                                             write_resource_flags,
                                             &wim->lzx_context);
@@ -1567,14 +1563,19 @@ wimlib_image_name_in_use(const WIMStruct *wim, const tchar *name)
 WIMLIBAPI int
 wimlib_get_xml_data(WIMStruct *wim, void **buf_ret, size_t *bufsize_ret)
 {
-       if (wim->filename == NULL)
+       const struct wim_reshdr *xml_reshdr;
+
+       if (wim->filename == NULL && filedes_is_seekable(&wim->in_fd))
                return WIMLIB_ERR_INVALID_PARAM;
 
        if (buf_ret == NULL || bufsize_ret == NULL)
                return WIMLIB_ERR_INVALID_PARAM;
 
-       *bufsize_ret = wim->hdr.xml_res_entry.original_size;
-       return res_entry_to_data(&wim->hdr.xml_res_entry, wim, buf_ret);
+       xml_reshdr = &wim->hdr.xml_data_reshdr;
+
+       DEBUG("Reading XML data.");
+       *bufsize_ret = xml_reshdr->uncompressed_size;
+       return wim_reshdr_to_data(xml_reshdr, wim, buf_ret);
 }
 
 WIMLIBAPI int