* This file is part of wimlib, a library for working with WIM files.
*
* wimlib is free software; you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free
- * Software Foundation; either version 2.1 of the License, or (at your option)
+ * terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
* any later version.
*
* wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
- * You should have received a copy of the GNU Lesser General Public License
+ * You should have received a copy of the GNU General Public License
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
#define INTEGRITY_CHUNK_SIZE 10485760
/*
- * Verifies the integrity of a WIM.
+ * Verifies the integrity of a WIM.
*
- * @fp: FILE* of the WIM, currently positioned at the end of the header.
+ * @fp: FILE* of the WIM, currently positioned at the end of the header.
* @num_bytes: Number of bytes to verify the integrity of.
* @chunk_size: Chunk size per SHA1 message digest.
* @sha1sums: Array of SHA1 message digests; 20 bytes each, one per chunk.
* @show_progress: Nonzero if the percent complete is to be printed after every
* chunk.
- * @status: On success, set to WIM_INTEGRITY_OK or WIM_INTEGRITY_NOT_OK
+ * @status: On success, set to WIM_INTEGRITY_OK or WIM_INTEGRITY_NOT_OK
* based on whether the WIM is intact or not.
*/
-static int verify_integrity(FILE *fp, u64 num_bytes, u32 chunk_size,
+static int verify_integrity(FILE *fp, u64 num_bytes, u32 chunk_size,
const u8 *sha1sums, int show_progress,
int *status)
{
bytes_remaining = num_bytes;
while (bytes_remaining != 0) {
if (show_progress) {
- percent_done = (num_bytes - bytes_remaining) * 100 /
+ percent_done = (num_bytes - bytes_remaining) * 100 /
num_bytes;
printf("Verifying integrity of WIM (%"PRIu64" bytes "
- "remaining, %u%% done) \r",
+ "remaining, %u%% done) \r",
bytes_remaining, percent_done);
fflush(stdout);
}
}
/*
- * Verifies the integrity of the WIM.
+ * Verifies the integrity of the WIM.
*
* @show_progress: Nonzero if the percent complete is to be printed after every
* chunk.
if (integrity_table_size != expected_size) {
ERROR("Integrity table is %u bytes, but expected %"PRIu64" "
- "bytes to hold %u entries",
+ "bytes to hold %u entries",
integrity_table_size, expected_size, num_entries);
ret = WIMLIB_ERR_INVALID_INTEGRITY_TABLE;
goto out;
end_lookup_table_offset = w->hdr.lookup_table_res_entry.offset +
w->hdr.lookup_table_res_entry.size;
+ if (end_lookup_table_offset < WIM_HEADER_DISK_SIZE) {
+ ERROR("WIM lookup table ends before WIM header ends???");
+ ret = WIMLIB_ERR_INVALID_INTEGRITY_TABLE;
+ goto out;
+ }
+
bytes_to_check = end_lookup_table_offset - WIM_HEADER_DISK_SIZE;
expected_num_entries = (bytes_to_check + chunk_size - 1) / chunk_size;
}
/* call verify_integrity(), which does the actual checking of the SHA1
* message digests. */
- ret = verify_integrity(w->fp, bytes_to_check, chunk_size, p,
+ ret = verify_integrity(w->fp, bytes_to_check, chunk_size, p,
show_progress, status);
out:
FREE(buf);
return ret;
}
-/*
+/*
* Writes integrity information to the output stream for a WIM file being
- * written.
+ * written.
*
* @end_header_offset is the offset of the byte after the header, which is the
* beginning of the region that is checksummed.
*
* @end_lookup_table_offset is the offset of the byte after the lookup table,
- * which is the end of the region that is checksummed.
+ * which is the end of the region that is checksummed.
*/
-int write_integrity_table(FILE *out, u64 end_header_offset,
+int write_integrity_table(FILE *out, u64 end_header_offset,
u64 end_lookup_table_offset, int show_progress)
{
- u64 bytes_to_check;
- u64 bytes_remaining;
- u8 *buf;
- u8 *p;
- u8 *chunk_buf;
- u32 num_entries;
- u32 integrity_table_size;
- int ret;
-
- DEBUG("Writing integrity table");
+ u64 bytes_to_check;
+ u64 bytes_remaining;
+ u8 *buf;
+ u8 *p;
+ u8 *chunk_buf;
+ u32 num_entries;
+ u32 integrity_table_size;
+ int ret;
+
+ DEBUG("Calculating integrity table");
if (fseeko(out, end_header_offset, SEEK_SET) != 0) {
ERROR_WITH_ERRNO("Failed to seek to byte %"PRIu64" of WIM to "
"calculate integrity data", end_header_offset);
}
bytes_to_check = end_lookup_table_offset - end_header_offset;
- num_entries = bytes_to_check / INTEGRITY_CHUNK_SIZE +
- (bytes_to_check % INTEGRITY_CHUNK_SIZE != 0);
+ num_entries = (bytes_to_check + INTEGRITY_CHUNK_SIZE - 1) /
+ INTEGRITY_CHUNK_SIZE;
integrity_table_size = num_entries * SHA1_HASH_SIZE + 3 * sizeof(u32);
- DEBUG("integrity table size = %u", integrity_table_size);
-
+ DEBUG("integrity_table_size = %u", integrity_table_size);
buf = MALLOC(integrity_table_size);
if (!buf) {
ERROR("Failed to allocate %u bytes for integrity chunk buffer",
INTEGRITY_CHUNK_SIZE);
ret = WIMLIB_ERR_NOMEM;
- goto err2;
+ goto out_free_buf;
}
bytes_remaining = bytes_to_check;
while (bytes_remaining != 0) {
- uint percent_done = (bytes_to_check - bytes_remaining) *
+ uint percent_done = (bytes_to_check - bytes_remaining) *
100 / bytes_to_check;
if (show_progress) {
printf("Calculating integrity checksums for WIM "
"(%"PRIu64" bytes remaining, %u%% "
- "done) \r",
+ "done) \r",
bytes_remaining, percent_done);
fflush(stdout);
}
"checksums");
}
ret = WIMLIB_ERR_READ;
- goto err2;
+ goto out_free_chunk_buf;
}
sha1_buffer(chunk_buf, bytes_read, p);
p += SHA1_HASH_SIZE;
ERROR_WITH_ERRNO("Failed to seek to end of WIM to write "
"integrity table");
ret = WIMLIB_ERR_WRITE;
- goto err1;
+ goto out_free_chunk_buf;
}
if (fwrite(buf, 1, integrity_table_size, out) != integrity_table_size) {
ERROR_WITH_ERRNO("Failed to write integrity table to end of "
"WIM");
ret = WIMLIB_ERR_WRITE;
- goto err1;
+ goto out_free_chunk_buf;
}
ret = 0;
-err1:
+out_free_chunk_buf:
FREE(chunk_buf);
-err2:
+out_free_buf:
FREE(buf);
return ret;
}