- if (integrity_table_size != expected_size) {
- ERROR("Integrity table is %u bytes, but expected %"PRIu64" "
- "bytes to hold %u entries",
- integrity_table_size, expected_size, num_entries);
- ret = WIMLIB_ERR_INVALID_INTEGRITY_TABLE;
- goto out;
+/*
+ * calculate_integrity_table():
+ *
+ * Calculates an integrity table for the data in a file beginning at offset 208
+ * (WIM_HEADER_DISK_SIZE).
+ *
+ * @in_fd:
+ * File descriptor for the file to be checked, opened for reading. Does
+ * not need to be at any specific location in the file.
+ *
+ * @new_check_end:
+ * Offset of byte after the last byte to be checked.
+ *
+ * @old_table:
+ * If non-NULL, a pointer to the table containing the previously calculated
+ * integrity data for a prefix of this file.
+ *
+ * @old_check_end:
+ * If @old_table is non-NULL, the byte after the last byte that was checked
+ * in the old table. Must be less than or equal to new_check_end.
+ *
+ * @progress_func:
+ * If non-NULL, a progress function that will be called after every
+ * calculated chunk.
+ *
+ * @integrity_table_ret:
+ * On success, a pointer to the calculated integrity table is written into
+ * this location.
+ *
+ * Return values:
+ * WIMLIB_ERR_SUCCESS (0)
+ * WIMLIB_ERR_NOMEM
+ * WIMLIB_ERR_READ
+ * WIMLIB_ERR_UNEXPECTED_END_OF_FILE
+ */
+static int
+calculate_integrity_table(struct filedes *in_fd,
+ off_t new_check_end,
+ const struct integrity_table *old_table,
+ off_t old_check_end,
+ wimlib_progress_func_t progress_func,
+ struct integrity_table **integrity_table_ret)
+{
+ int ret;
+ size_t chunk_size = INTEGRITY_CHUNK_SIZE;
+
+ /* If an old table is provided, set the chunk size to be compatible with
+ * the old chunk size, unless the old chunk size was weird. */
+ if (old_table != NULL) {
+ if (old_table->num_entries == 0 ||
+ old_table->chunk_size < INTEGRITY_MIN_CHUNK_SIZE ||
+ old_table->chunk_size > INTEGRITY_MAX_CHUNK_SIZE)
+ old_table = NULL;
+ else
+ chunk_size = old_table->chunk_size;