+
+ /* 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;
+
+ /* Save previous header, then start initializing the new one. */
+ memcpy(&hdr_save, &wim->hdr, sizeof(struct wim_header));
+
+ /* Set default integrity and pipable flags. */
+ if (!(write_flags & (WIMLIB_WRITE_FLAG_PIPABLE |
+ WIMLIB_WRITE_FLAG_NOT_PIPABLE)))
+ if (wim_is_pipable(wim))
+ 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))
+ write_flags |= WIMLIB_WRITE_FLAG_CHECK_INTEGRITY;
+
+ /* Set appropriate magic number. */
+ if (write_flags & WIMLIB_WRITE_FLAG_PIPABLE)
+ wim->hdr.magic = PWM_MAGIC;
+ else
+ wim->hdr.magic = WIM_MAGIC;
+
+ /* Clear header flags that will be set automatically. */
+ wim->hdr.flags &= ~(WIM_HDR_FLAG_METADATA_ONLY |
+ WIM_HDR_FLAG_RESOURCE_ONLY |
+ WIM_HDR_FLAG_SPANNED |
+ WIM_HDR_FLAG_WRITE_IN_PROGRESS);
+
+ /* Set SPANNED header flag if writing part of a split WIM. */
+ if (total_parts != 1)
+ wim->hdr.flags |= WIM_HDR_FLAG_SPANNED;
+
+ /* Set part number and total parts of split WIM. This will be 1 and 1
+ * if the WIM is standalone. */
+ wim->hdr.part_number = part_number;
+ wim->hdr.total_parts = total_parts;
+
+ /* Use GUID if specified; otherwise generate a new one. */
+ if (guid)
+ memcpy(wim->hdr.guid, guid, WIMLIB_GUID_LEN);
+ else
+ randomize_byte_array(wim->hdr.guid, WIMLIB_GUID_LEN);
+
+ /* Clear references to resources that have not been written yet. */
+ zero_resource_entry(&wim->hdr.lookup_table_res_entry);
+ zero_resource_entry(&wim->hdr.xml_res_entry);
+ zero_resource_entry(&wim->hdr.boot_metadata_res_entry);
+ zero_resource_entry(&wim->hdr.integrity);
+
+ /* Set image count and boot index correctly for single image writes. */
+ if (image != WIMLIB_ALL_IMAGES) {
+ wim->hdr.image_count = 1;
+ if (wim->hdr.boot_idx == image)
+ wim->hdr.boot_idx = 1;
+ else
+ wim->hdr.boot_idx = 0;
+ }
+
+ /* Split WIMs can't be bootable. */
+ if (total_parts != 1)
+ wim->hdr.boot_idx = 0;
+
+ /* Initialize output file descriptor. */
+ if (write_flags & WIMLIB_WRITE_FLAG_FILE_DESCRIPTOR) {
+ /* File descriptor was explicitly provided. Return error if
+ * file descriptor is not seekable, unless writing a pipable WIM
+ * was requested. */
+ wim->out_fd.fd = *(const int*)path_or_fd;
+ wim->out_fd.offset = 0;
+ if (!filedes_is_seekable(&wim->out_fd)) {
+ ret = WIMLIB_ERR_INVALID_PARAM;
+ if (!(write_flags & WIMLIB_WRITE_FLAG_PIPABLE))
+ goto out_restore_hdr;
+ if (write_flags & WIMLIB_WRITE_FLAG_CHECK_INTEGRITY) {
+ ERROR("Can't include integrity check when "
+ "writing pipable WIM to pipe!");
+ goto out_restore_hdr;
+ }
+ }
+
+ } else {
+ /* Filename of WIM to write was provided; open file descriptor
+ * to it. */
+ ret = open_wim_writable(wim, (const tchar*)path_or_fd,
+ O_TRUNC | O_CREAT | O_RDWR);
+ if (ret)
+ goto out_restore_hdr;