+ int ret;
+ struct wim_header hdr_save;
+ struct list_head lookup_table_list;
+
+ if (total_parts == 1)
+ DEBUG("Writing standalone WIM.");
+ else
+ DEBUG("Writing split WIM part %u/%u", part_number, total_parts);
+ if (image == WIMLIB_ALL_IMAGES)
+ DEBUG("Including all images.");
+ else
+ DEBUG("Including image %d only.", image);
+ if (write_flags & WIMLIB_WRITE_FLAG_FILE_DESCRIPTOR)
+ DEBUG("File descriptor: %d", *(const int*)path_or_fd);
+ else
+ DEBUG("Path: \"%"TS"\"", (const tchar*)path_or_fd);
+ DEBUG("Write flags: 0x%08x", write_flags);
+
+ if (write_flags & WIMLIB_WRITE_FLAG_CHECK_INTEGRITY)
+ DEBUG("\tCHECK_INTEGRITY");
+
+ if (write_flags & WIMLIB_WRITE_FLAG_REBUILD)
+ DEBUG("\tREBUILD");
+
+ if (write_flags & WIMLIB_WRITE_FLAG_RECOMPRESS)
+ DEBUG("\tRECOMPRESS");
+
+ if (write_flags & WIMLIB_WRITE_FLAG_FSYNC)
+ DEBUG("\tFSYNC");
+
+ if (write_flags & WIMLIB_WRITE_FLAG_SOFT_DELETE)
+ DEBUG("\tFSYNC");
+
+ if (write_flags & WIMLIB_WRITE_FLAG_IGNORE_READONLY_FLAG)
+ DEBUG("\tIGNORE_READONLY_FLAG");
+
+ if (write_flags & WIMLIB_WRITE_FLAG_PIPABLE)
+ DEBUG("\tPIPABLE");
+
+ if (write_flags & WIMLIB_WRITE_FLAG_NOT_PIPABLE)
+ DEBUG("\tNOT_PIPABLE");
+
+ if (write_flags & WIMLIB_WRITE_FLAG_PACK_STREAMS)
+ DEBUG("\tPACK_STREAMS");
+
+ if (write_flags & WIMLIB_WRITE_FLAG_NO_PACK_STREAMS)
+ DEBUG("\tNO_PACK_STREAMS");
+
+ if (write_flags & WIMLIB_WRITE_FLAG_FILE_DESCRIPTOR)
+ DEBUG("\tFILE_DESCRIPTOR");
+
+ if (write_flags & WIMLIB_WRITE_FLAG_NO_METADATA)
+ DEBUG("\tNO_METADATA");
+
+ if (write_flags & WIMLIB_WRITE_FLAG_USE_EXISTING_TOTALBYTES)
+ DEBUG("\tUSE_EXISTING_TOTALBYTES");
+
+ if (num_threads == 0)
+ DEBUG("Number of threads: autodetect");
+ else
+ DEBUG("Number of threads: %u", num_threads);
+ DEBUG("Progress function: %s", (progress_func ? "yes" : "no"));
+ DEBUG("Stream list: %s", (stream_list_override ? "specified" : "autodetect"));
+ DEBUG("GUID: %s", ((guid || wim->guid_set_explicitly) ?
+ "specified" : "generate new"));
+
+ /* Internally, this is always called with a valid part number and total
+ * parts. */
+ wimlib_assert(total_parts >= 1);
+ wimlib_assert(part_number >= 1 && part_number <= total_parts);
+
+ /* A valid image (or all images) must be specified. */
+ if (image != WIMLIB_ALL_IMAGES &&
+ (image < 1 || image > wim->hdr.image_count))
+ return WIMLIB_ERR_INVALID_IMAGE;
+
+ /* If we need to write metadata resources, make sure the ::WIMStruct has
+ * the needed information attached (e.g. is not a resource-only WIM,
+ * such as a non-first part of a split WIM). */
+ if (!wim_has_metadata(wim) &&
+ !(write_flags & WIMLIB_WRITE_FLAG_NO_METADATA))
+ return WIMLIB_ERR_METADATA_NOT_FOUND;
+
+ /* Check for contradictory flags. */
+ if ((write_flags & (WIMLIB_WRITE_FLAG_CHECK_INTEGRITY |
+ WIMLIB_WRITE_FLAG_NO_CHECK_INTEGRITY))
+ == (WIMLIB_WRITE_FLAG_CHECK_INTEGRITY |
+ WIMLIB_WRITE_FLAG_NO_CHECK_INTEGRITY))
+ return WIMLIB_ERR_INVALID_PARAM;
+
+ if ((write_flags & (WIMLIB_WRITE_FLAG_PIPABLE |
+ WIMLIB_WRITE_FLAG_NOT_PIPABLE))
+ == (WIMLIB_WRITE_FLAG_PIPABLE |
+ WIMLIB_WRITE_FLAG_NOT_PIPABLE))
+ return WIMLIB_ERR_INVALID_PARAM;
+
+ if ((write_flags & (WIMLIB_WRITE_FLAG_PACK_STREAMS |
+ WIMLIB_WRITE_FLAG_NO_PACK_STREAMS))
+ == (WIMLIB_WRITE_FLAG_PACK_STREAMS |
+ WIMLIB_WRITE_FLAG_NO_PACK_STREAMS))
+ return WIMLIB_ERR_INVALID_PARAM;
+
+ /* Save previous header, then start initializing the new one. */
+ memcpy(&hdr_save, &wim->hdr, sizeof(struct wim_header));
+
+ /* Set default integrity, pipable, and packed stream flags. */
+ if (!(write_flags & (WIMLIB_WRITE_FLAG_PIPABLE |
+ WIMLIB_WRITE_FLAG_NOT_PIPABLE)))
+ if (wim_is_pipable(wim)) {
+ DEBUG("WIM is pipable; default to PIPABLE.");
+ write_flags |= WIMLIB_WRITE_FLAG_PIPABLE;
+ }
+
+ if (!(write_flags & (WIMLIB_WRITE_FLAG_CHECK_INTEGRITY |
+ WIMLIB_WRITE_FLAG_NO_CHECK_INTEGRITY)))
+ if (wim_has_integrity_table(wim)) {
+ DEBUG("Integrity table present; default to CHECK_INTEGRITY.");
+ write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY;