]> wimlib.net Git - wimlib/blobdiff - src/header.c
wim.c: Cleanup
[wimlib] / src / header.c
index 906d8e75cddebe5defa188ee3bba1855f82b5d6d..4924b505dfba8f6e455733ddcb0e67722ba70e9f 100644 (file)
 #  include <stdlib.h>
 #endif
 
-/* On-disk format of the WIM header. */
-struct wim_header_disk {
-
-       /* Magic characters "MSWIM\0\0\0" */
-       le64 magic;
-
-       /* Size of the WIM header, in bytes; WIM_HEADER_DISK_SIZE expected
-        * (currently the only supported value). */
-       u32 hdr_size;
-
-       /* Version of the WIM file; WIM_VERSION expected (currently the only
-        * supported value). */
-       u32 wim_version;
-
-       /* Flags for the WIM file (WIM_HDR_FLAG_*) */
-       u32 wim_flags;
-
-       /* Uncompressed chunk size of resources in the WIM.  0 if the WIM is
-        * uncompressed.  If compressed, WIM_CHUNK_SIZE is expected (currently
-        * the only supported value).  */
-       u32 chunk_size;
-
-       /* Globally unique identifier for the WIM file.  Basically a bunch of
-        * random bytes. */
-       u8 guid[WIM_GID_LEN];
-
-       /* Number of this WIM part in the split WIM file, indexed from 1, or 1
-        * if the WIM is not split. */
-       u16 part_number;
-
-       /* Total number of parts of the split WIM file, or 1 if the WIM is not
-        * split. */
-       u16 total_parts;
-
-       /* Number of images in the WIM. */
-       u32 image_count;
-
-       /* Location and size of the WIM's lookup table. */
-       struct resource_entry_disk lookup_table_res_entry;
-
-       /* Location and size of the WIM's XML data. */
-       struct resource_entry_disk xml_data_res_entry;
-
-       /* 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;
-
-       /* 1-based index of the bootable image of the WIM, or 0 if no image is
-        * bootable. */
-       u32 boot_idx;
-
-       /* 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
-        * 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;
-
-       /* Unused bytes. */
-       u8 unused[60];
-} _packed_attribute;
-
 /*
  * Reads the header from a WIM file.
  *
@@ -139,7 +76,7 @@ read_wim_header(const tchar *filename, struct filedes *in_fd,
 
        wimlib_assert(in_fd->offset == 0);
 
-       if (!filename) {
+       if (filename == NULL) {
                pipe_str = alloca(40);
                tsprintf(pipe_str, T("[fd %d]"), in_fd->fd);
                filename = pipe_str;
@@ -180,21 +117,16 @@ read_wim_header(const tchar *filename, struct filedes *in_fd,
                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);
+               }
                return WIMLIB_ERR_UNKNOWN_VERSION;
        }
 
        hdr->flags = le32_to_cpu(disk_hdr.wim_flags);
-       if (le32_to_cpu(disk_hdr.chunk_size) != WIM_CHUNK_SIZE &&
-           (hdr->flags & WIM_HDR_FLAG_COMPRESSION)) {
-               ERROR("\"%"TS"\": Unexpected chunk size of %u! Ask the author to "
-                     "implement support for other chunk sizes.",
-                     filename, le32_to_cpu(disk_hdr.chunk_size));
-               ERROR("(Or it might just be that the WIM header is invalid.)");
-               return WIMLIB_ERR_INVALID_CHUNK_SIZE;
-       }
-
+       hdr->chunk_size = le32_to_cpu(disk_hdr.chunk_size);
        memcpy(hdr->guid, disk_hdr.guid, WIM_GID_LEN);
-
        hdr->part_number = le16_to_cpu(disk_hdr.part_number);
        hdr->total_parts = le16_to_cpu(disk_hdr.total_parts);
 
@@ -247,8 +179,10 @@ write_wim_header_at_offset(const struct wim_header *hdr, struct filedes *out_fd,
        disk_hdr.hdr_size = cpu_to_le32(sizeof(struct wim_header_disk));
        disk_hdr.wim_version = cpu_to_le32(WIM_VERSION);
        disk_hdr.wim_flags = cpu_to_le32(hdr->flags);
-       disk_hdr.chunk_size = cpu_to_le32((hdr->flags & WIM_HDR_FLAG_COMPRESSION) ?
-                                               WIM_CHUNK_SIZE : 0);
+       if (hdr->flags & WIM_HDR_FLAG_COMPRESSION)
+               disk_hdr.chunk_size = cpu_to_le32(hdr->chunk_size);
+       else
+               disk_hdr.chunk_size = 0;
        memcpy(disk_hdr.guid, hdr->guid, WIM_GID_LEN);
 
        disk_hdr.part_number = cpu_to_le16(hdr->part_number);
@@ -288,33 +222,48 @@ write_wim_header_flags(u32 hdr_flags, struct filedes *out_fd)
                           offsetof(struct wim_header_disk, wim_flags));
 }
 
-/*
- * Initializes the header for a WIM file.
- */
 int
-init_wim_header(struct wim_header *hdr, int ctype)
+set_wim_hdr_cflags(int ctype, struct wim_header *hdr)
 {
-       memset(hdr, 0, sizeof(struct wim_header));
+       hdr->flags &= ~(WIM_HDR_FLAG_COMPRESSION |
+                       WIM_HDR_FLAG_COMPRESS_LZX |
+                       WIM_HDR_FLAG_COMPRESS_RESERVED |
+                       WIM_HDR_FLAG_COMPRESS_XPRESS |
+                       WIM_HDR_FLAG_COMPRESS_LZMS);
        switch (ctype) {
+
        case WIMLIB_COMPRESSION_TYPE_NONE:
-               hdr->flags = 0;
-               break;
+               return 0;
+
        case WIMLIB_COMPRESSION_TYPE_LZX:
-               hdr->flags = WIM_HDR_FLAG_COMPRESSION |
-                            WIM_HDR_FLAG_COMPRESS_LZX;
-               break;
+               hdr->flags |= WIM_HDR_FLAG_COMPRESSION | WIM_HDR_FLAG_COMPRESS_LZX;
+               return 0;
+
        case WIMLIB_COMPRESSION_TYPE_XPRESS:
-               hdr->flags = WIM_HDR_FLAG_COMPRESSION |
-                            WIM_HDR_FLAG_COMPRESS_XPRESS;
-               break;
+               hdr->flags |= WIM_HDR_FLAG_COMPRESSION | WIM_HDR_FLAG_COMPRESS_XPRESS;
+               return 0;
+
        default:
+               return WIMLIB_ERR_INVALID_COMPRESSION_TYPE;
+       }
+}
+
+/*
+ * Initializes the header for a WIM file.
+ */
+int
+init_wim_header(struct wim_header *hdr, int ctype, u32 chunk_size)
+{
+       memset(hdr, 0, sizeof(struct wim_header));
+       hdr->magic = WIM_MAGIC;
+       if (set_wim_hdr_cflags(ctype, hdr)) {
                ERROR("Invalid compression type specified (%d)", ctype);
                return WIMLIB_ERR_INVALID_COMPRESSION_TYPE;
        }
+       hdr->chunk_size = chunk_size;
        hdr->total_parts = 1;
        hdr->part_number = 1;
        randomize_byte_array(hdr->guid, sizeof(hdr->guid));
-       hdr->magic = WIM_MAGIC;
        return 0;
 }
 
@@ -351,7 +300,7 @@ wimlib_print_header(const WIMStruct *wim)
                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_CHUNK_SIZE);
+       tprintf(T("Chunk Size                  = %u\n"), wim->hdr.chunk_size);
        tfputs (T("GUID                        = "), stdout);
        print_byte_field(hdr->guid, WIM_GID_LEN, stdout);
        tputchar(T('\n'));