Empty file fix
authorEric Biggers <ebiggers3@gmail.com>
Sun, 20 May 2012 15:53:02 +0000 (10:53 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sun, 20 May 2012 15:53:02 +0000 (10:53 -0500)
imagex.exe expects empty files to have a zeroed-out hash (despite the fact this
isn't actually the hash of the empty file) and no lookup table entry.  This
patch makes this the case for the WIMs that wimlib writes.

src/dentry.c
src/lookup_table.c
src/resource.c
src/sha1.c
src/sha1.h

index 6f6822e..7f41853 100644 (file)
@@ -32,6 +32,7 @@
 #include "io.h"
 #include "timestamp.h"
 #include "lookup_table.h"
+#include "sha1.h"
 #include <unistd.h>
 #include <sys/stat.h>
 
@@ -750,7 +751,11 @@ static u8 *write_dentry(const struct dentry *dentry, u8 *p)
        p = put_u64(p, dentry->creation_time);
        p = put_u64(p, dentry->last_access_time);
        p = put_u64(p, dentry->last_write_time);
-       p = put_bytes(p, WIM_HASH_SIZE, dentry->hash);
+       if (!is_empty_file_hash(dentry->hash))
+               memcpy(p, dentry->hash, WIM_HASH_SIZE);
+       else
+               printf("zero hash for %s\n", dentry->file_name_utf8);
+       p += WIM_HASH_SIZE;
        p = put_u32(p, 0); /* reparse_tag */
        p = put_u64(p, dentry->hard_link);
        p = put_u16(p, 0); /*streams */
index 3bb77a4..46ab456 100644 (file)
@@ -264,14 +264,17 @@ int write_lookup_table_entry(struct lookup_table_entry *lte, void *__out)
 
        out = __out;
 
+       /* do not write lookup table entries for empty files */
+       if (lte->output_resource_entry.original_size == 0)
+               return 0;
+
        /* Don't write entries that have not had file resources or metadata
         * resources written for them. */
        if (lte->out_refcnt == 0)
                return 0;
 
-       if (lte->output_resource_entry.flags & WIM_RESHDR_FLAG_METADATA) {
+       if (lte->output_resource_entry.flags & WIM_RESHDR_FLAG_METADATA)
                DEBUG("Writing metadata entry at %lu\n", ftello(out));
-       }
 
        p = put_resource_entry(buf, &lte->output_resource_entry);
        p = put_u16(p, lte->part_number);
index b525f22..e29434f 100644 (file)
@@ -1112,8 +1112,6 @@ int write_file_resource(struct dentry *dentry, void *wim_p)
        struct lookup_table_entry *lte;
        int in_wim_ctype;
        int out_wim_ctype;
-       int input_res_ctype;
-       struct resource_entry *input_res_entry;
        struct resource_entry *output_res_entry;
        u64 len;
        int ret;
@@ -1138,6 +1136,10 @@ int write_file_resource(struct dentry *dentry, void *wim_p)
        out_wim_ctype = wimlib_get_compression_type(w);
        output_res_entry = &lte->output_resource_entry;
 
+       /* do not write empty resources */
+       if (lte->resource_entry.original_size == 0)
+               return 0;
+
        /* Figure out if we can read the resource from the WIM file, or
         * if we have to read it from the filesystem outside. */
        if (lte->file_on_disk) {
@@ -1175,15 +1177,14 @@ int write_file_resource(struct dentry *dentry, void *wim_p)
                        in = w->fp;
                        in_wim_ctype = out_wim_ctype;
                }
-               input_res_entry = &lte->resource_entry;
-               input_res_ctype = resource_compression_type(
+               int input_res_ctype = resource_compression_type(
                                        in_wim_ctype, 
-                                       input_res_entry->flags);
+                                       lte->resource_entry.flags);
 
                ret = transfer_file_resource(in, 
-                                       input_res_entry->size,
-                                       input_res_entry->original_size, 
-                                       input_res_entry->offset,
+                                       lte->resource_entry.size,
+                                       lte->resource_entry.original_size, 
+                                       lte->resource_entry.offset,
                                        input_res_ctype, 
                                        out, 
                                        out_wim_ctype,
index b0746bc..ff582ed 100644 (file)
 #error "invalid BLOCKSIZE"
 #endif
 
+const u8 empty_file_sha1sum[SHA1_HASH_SIZE] = {
+       0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 
+       0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09,
+};
+
 
 #ifdef WITH_LIBCRYPTO
 
index e73b62a..7ec8456 100644 (file)
@@ -4,6 +4,16 @@
 #include "config.h"
 #include <stdio.h>
 #include <stddef.h>
+#include "string.h"
+
+#define SHA1_HASH_SIZE 20
+
+extern const u8 empty_file_sha1sum[SHA1_HASH_SIZE];
+
+static inline bool is_empty_file_hash(const u8 hash[SHA1_HASH_SIZE])
+{
+       return memcmp(hash, empty_file_sha1sum, SHA1_HASH_SIZE) == 0;
+}
 
 /* Compute SHA1 message digest for bytes read from STREAM.  The
    resulting message digest number will be written into the 20 bytes