X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fexport_image.c;h=34b92422c1aabafb25e156034c6c784df2f6c0c3;hp=b769afc2e97179b3b2f3740096b4f4c8bde48bd1;hb=b5b9681794d1f5f13350e3567f6f6e74f5c779cf;hpb=465a630d28e93b09e55ca07b1a6cae8def3b42f5 diff --git a/src/export_image.c b/src/export_image.c index b769afc2..34b92422 100644 --- a/src/export_image.c +++ b/src/export_image.c @@ -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" @@ -35,14 +36,15 @@ 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; } @@ -101,8 +110,7 @@ wimlib_export_image(WIMStruct *src_wim, WIMStruct *dest_wim, const tchar *dest_name, const tchar *dest_description, - int export_flags, - wimlib_progress_func_t progress_func) + int export_flags) { int ret; int start_image; @@ -112,10 +120,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 +188,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 +199,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 +229,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 +263,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;