]> wimlib.net Git - wimlib/blobdiff - src/export_image.c
wimexport: Add --wimboot flag
[wimlib] / src / export_image.c
index b769afc2e97179b3b2f3740096b4f4c8bde48bd1..9c25be732eb8d9424bd30ecd905ec50159de271d 100644 (file)
@@ -28,6 +28,7 @@
 #include "wimlib.h"
 #include "wimlib/dentry.h"
 #include "wimlib/error.h"
+#include "wimlib/inode.h"
 #include "wimlib/lookup_table.h"
 #include "wimlib/metadata.h"
 #include "wimlib/xml.h"
 
 static int
 inode_export_streams(struct wim_inode *inode,
-                    const struct wim_lookup_table *src_lookup_table,
-                    struct wim_lookup_table *dest_lookup_table)
+                    struct wim_lookup_table *src_lookup_table,
+                    struct wim_lookup_table *dest_lookup_table,
+                    bool gift)
 {
        unsigned i;
        const u8 *hash;
        struct wim_lookup_table_entry *src_lte, *dest_lte;
 
-       inode_unresolve_ltes(inode);
+       inode_unresolve_streams(inode);
        for (i = 0; i <= inode->i_num_ads; i++) {
 
                /* Retrieve SHA1 message digest of stream to export.  */
@@ -52,18 +54,23 @@ inode_export_streams(struct wim_inode *inode,
 
                /* Search for the stream (via SHA1 message digest) in the
                 * destination WIM.  */
-               dest_lte = lookup_resource(dest_lookup_table, hash);
+               dest_lte = lookup_stream(dest_lookup_table, hash);
                if (!dest_lte) {
                        /* Stream not yet present in destination WIM.  Search
                         * for it in the source WIM, then export it into the
                         * destination WIM.  */
-                       src_lte = lookup_resource(src_lookup_table, hash);
+                       src_lte = lookup_stream(src_lookup_table, hash);
                        if (!src_lte)
-                               return resource_not_found_error(inode, hash);
-
-                       dest_lte = clone_lookup_table_entry(src_lte);
-                       if (!dest_lte)
-                               return WIMLIB_ERR_NOMEM;
+                               return stream_not_found_error(inode, hash);
+
+                       if (gift) {
+                               dest_lte = src_lte;
+                               lookup_table_unlink(src_lookup_table, src_lte);
+                       } else {
+                               dest_lte = clone_lookup_table_entry(src_lte);
+                               if (!dest_lte)
+                                       return WIMLIB_ERR_NOMEM;
+                       }
                        dest_lte->refcnt = 0;
                        dest_lte->out_refcnt = 0;
                        lookup_table_insert(dest_lookup_table, dest_lte);
@@ -86,10 +93,12 @@ lte_unexport(struct wim_lookup_table_entry *lte, void *_lookup_table)
 {
        struct wim_lookup_table *lookup_table = _lookup_table;
 
-       lte->refcnt -= lte->out_refcnt;
-       if (lte->refcnt == 0) {
-               lookup_table_unlink(lookup_table, lte);
-               free_lookup_table_entry(lte);
+       if (lte->out_refcnt) {
+               lte->refcnt -= lte->out_refcnt;
+               if (lte->refcnt == 0) {
+                       lookup_table_unlink(lookup_table, lte);
+                       free_lookup_table_entry(lte);
+               }
        }
        return 0;
 }
@@ -112,10 +121,17 @@ wimlib_export_image(WIMStruct *src_wim,
        u32 orig_dest_image_count;
 
        /* Check for sane parameters.  */
+       if (export_flags & ~(WIMLIB_EXPORT_FLAG_BOOT |
+                            WIMLIB_EXPORT_FLAG_NO_NAMES |
+                            WIMLIB_EXPORT_FLAG_NO_DESCRIPTIONS |
+                            WIMLIB_EXPORT_FLAG_GIFT |
+                            WIMLIB_EXPORT_FLAG_WIMBOOT))
+               return WIMLIB_ERR_INVALID_PARAM;
+
        if (src_wim == NULL || dest_wim == NULL)
                return WIMLIB_ERR_INVALID_PARAM;
 
-       if (!wim_has_metadata(src_wim) || !wim_has_metadata(dest_wim))
+       if (!wim_has_metadata(dest_wim))
                return WIMLIB_ERR_METADATA_NOT_FOUND;
 
        /* Destination WIM must be writable.  */
@@ -173,7 +189,7 @@ wimlib_export_image(WIMStruct *src_wim,
                /* Determine destination image name and description.  */
 
                if (export_flags & WIMLIB_EXPORT_FLAG_NO_NAMES) {
-                       next_dest_name = NULL;
+                       next_dest_name = T("");
                } else if (dest_name) {
                        next_dest_name = dest_name;
                } else {
@@ -184,8 +200,8 @@ wimlib_export_image(WIMStruct *src_wim,
                DEBUG("Using name \"%"TS"\"", next_dest_name);
 
                if (export_flags & WIMLIB_EXPORT_FLAG_NO_DESCRIPTIONS) {
-                       next_dest_description = NULL;
-               } if (dest_description) {
+                       next_dest_description = T("");
+               } else if (dest_description) {
                        next_dest_description = dest_description;
                } else {
                        next_dest_description = wimlib_get_image_description(
@@ -214,7 +230,8 @@ wimlib_export_image(WIMStruct *src_wim,
                image_for_each_inode(inode, src_imd) {
                        ret = inode_export_streams(inode,
                                                   src_wim->lookup_table,
-                                                  dest_wim->lookup_table);
+                                                  dest_wim->lookup_table,
+                                                  export_flags & WIMLIB_EXPORT_FLAG_GIFT);
                        if (ret)
                                goto out_rollback;
                }
@@ -247,11 +264,23 @@ wimlib_export_image(WIMStruct *src_wim,
                        dest_wim->hdr.boot_idx = dest_wim->hdr.image_count;
                }
 
+               /* Possibly set WIMBoot flag  */
+               if (export_flags & WIMLIB_EXPORT_FLAG_WIMBOOT) {
+                       wim_info_set_wimboot(dest_wim->wim_info,
+                                            dest_wim->hdr.image_count,
+                                            true);
+               }
+
        }
        /* Set the reparse point fixup flag on the destination WIM if the flag
         * is set on the source WIM. */
        if (src_wim->hdr.flags & WIM_HDR_FLAG_RP_FIX)
                dest_wim->hdr.flags |= WIM_HDR_FLAG_RP_FIX;
+
+       if (export_flags & WIMLIB_EXPORT_FLAG_GIFT) {
+               free_lookup_table(src_wim->lookup_table);
+               src_wim->lookup_table = NULL;
+       }
        DEBUG("Export operation successful.");
        return 0;