+ default_extract_flags &= WIMLIB_EXTRACT_MASK_PUBLIC;
+
+ ret = verify_swm_set(wim, additional_swms, num_additional_swms);
+ if (ret)
+ goto out;
+
+ if (num_cmds == 0)
+ goto out;
+
+ if (num_additional_swms)
+ merge_lookup_tables(wim, additional_swms, num_additional_swms);
+
+ cmds_copy = CALLOC(num_cmds, sizeof(cmds[0]));
+ if (!cmds_copy) {
+ ret = WIMLIB_ERR_NOMEM;
+ goto out_restore_lookup_table;
+ }
+
+ for (size_t i = 0; i < num_cmds; i++) {
+ cmds_copy[i].extract_flags = (default_extract_flags |
+ cmds[i].extract_flags)
+ & WIMLIB_EXTRACT_MASK_PUBLIC;
+ all_flags |= cmds_copy[i].extract_flags;
+
+ cmds_copy[i].wim_source_path = canonicalize_wim_path(cmds[i].wim_source_path);
+ if (!cmds_copy[i].wim_source_path) {
+ ret = WIMLIB_ERR_NOMEM;
+ goto out_free_cmds_copy;
+ }
+
+ cmds_copy[i].fs_dest_path = canonicalize_fs_path(cmds[i].fs_dest_path);
+ if (!cmds_copy[i].fs_dest_path) {
+ ret = WIMLIB_ERR_NOMEM;
+ goto out_free_cmds_copy;
+ }
+
+ }
+ ret = do_wimlib_extract_files(wim, image,
+ cmds_copy, num_cmds,
+ progress_func);
+
+ if (all_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK |
+ WIMLIB_EXTRACT_FLAG_HARDLINK))
+ {
+ for_lookup_table_entry(wim->lookup_table,
+ lte_free_extracted_file, NULL);
+ }
+out_free_cmds_copy:
+ for (size_t i = 0; i < num_cmds; i++) {
+ FREE(cmds_copy[i].wim_source_path);
+ FREE(cmds_copy[i].fs_dest_path);
+ }
+ FREE(cmds_copy);
+out_restore_lookup_table:
+ if (num_additional_swms)
+ unmerge_lookup_table(wim);
+out:
+ return ret;
+}
+
+/*
+ * Extracts an image from a WIM file.
+ *
+ * @wim: WIMStruct for the WIM file.
+ *
+ * @image: Number of the single image to extract.
+ *
+ * @target: Directory or NTFS volume to extract the image to.
+ *
+ * @extract_flags: Bitwise or of WIMLIB_EXTRACT_FLAG_*.
+ *
+ * @progress_func: If non-NULL, a progress function to be called
+ * periodically.
+ *
+ * Returns 0 on success; nonzero on failure.
+ */
+static int
+extract_single_image(WIMStruct *wim, int image,
+ const tchar *target, int extract_flags,
+ wimlib_progress_func_t progress_func)
+{
+ int ret;
+ tchar *target_copy = canonicalize_fs_path(target);
+ if (!target_copy)
+ return WIMLIB_ERR_NOMEM;
+ struct wimlib_extract_command cmd = {
+ .wim_source_path = T(""),
+ .fs_dest_path = target_copy,