+/*
+ * Writes a WIM integrity table (a list of SHA1 message digests of raw 10 MiB
+ * 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
+ * @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
+ * re-calculated.
+ *
+ * @fp:
+ * FILE * to the WIM file, opened read-write, positioned at the location at
+ * which the integrity table is to be written.
+ *
+ * @integrity_res_entry:
+ * Resource entry which will be set to point to the integrity table on
+ * success. In addition, if @old_lookup_table_end != 0, this initially
+ * must point to the resource entry for the old integrity table for the
+ * WIM.
+ *
+ * @new_lookup_table_end:
+ * The offset of the byte directly following the lookup table in the WIM
+ * being written.
+ *
+ * @old_lookup_table_end:
+ * If nonzero, the offset of the byte directly following the old lookup
+ * table in the WIM.
+ *
+ * @progress_func
+ * If non-NULL, a progress function that will be called after every
+ * calculated chunk.
+ *
+ * Returns:
+ * 0 on success, nonzero on failure. The possible error codes are:
+ * * WIMLIB_ERR_WRITE: Could not write the integrity table.
+ * * WIMLIB_ERR_READ: Could not read a chunk of data that needed
+ * to be checked.
+ */
+int write_integrity_table(FILE *fp,
+ struct resource_entry *integrity_res_entry,
+ off_t new_lookup_table_end,
+ off_t old_lookup_table_end,
+ wimlib_progress_func_t progress_func)
+{
+ struct integrity_table *old_table;
+ struct integrity_table *new_table;
+ int ret;
+ off_t cur_offset;
+ u32 new_table_size;
+
+ wimlib_assert(old_lookup_table_end <= new_lookup_table_end);
+
+ cur_offset = ftello(fp);
+ if (cur_offset == -1)
+ return WIMLIB_ERR_WRITE;
+
+ if (integrity_res_entry->offset == 0 || old_lookup_table_end == 0) {
+ old_table = NULL;
+ } else {
+ ret = read_integrity_table(integrity_res_entry, fp,
+ old_lookup_table_end - WIM_HEADER_DISK_SIZE,
+ &old_table);
+ if (ret == WIMLIB_ERR_INVALID_INTEGRITY_TABLE) {
+ WARNING("Old integrity table is invalid! "
+ "Ignoring it");
+ } else if (ret != 0) {
+ WARNING("Can't read old integrity table! "
+ "Ignoring it");
+ }