X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fexport_image.c;h=c5c85d5f77f401070693ed42f8016c6e0b37b162;hp=dfd9f058ffdd344a39022e0e44c4b8a5f20f982d;hb=87836fae536b056cde1e84904a63ace9f8b7f707;hpb=276f9f9f9658f4a8bafd6216db46760abe8c848d diff --git a/src/export_image.c b/src/export_image.c index dfd9f058..c5c85d5f 100644 --- a/src/export_image.c +++ b/src/export_image.c @@ -26,10 +26,11 @@ #include "lookup_table.h" #include "xml.h" -static int inode_allocate_needed_ltes(struct wim_inode *inode, - struct wim_lookup_table *src_lookup_table, - struct wim_lookup_table *dest_lookup_table, - struct list_head *lte_list_head) +static int +inode_allocate_needed_ltes(struct wim_inode *inode, + struct wim_lookup_table *src_lookup_table, + struct wim_lookup_table *dest_lookup_table, + struct list_head *lte_list_head) { struct wim_lookup_table_entry *src_lte, *dest_lte; unsigned i; @@ -46,24 +47,22 @@ static int inode_allocate_needed_ltes(struct wim_inode *inode, dest_lte = clone_lookup_table_entry(src_lte); if (!dest_lte) return WIMLIB_ERR_NOMEM; - list_add_tail(&dest_lte->staging_list, lte_list_head); + list_add_tail(&dest_lte->export_stream_list, + lte_list_head); } } } return 0; } -static void inode_move_ltes_to_table(struct wim_inode *inode, - struct wim_lookup_table *src_lookup_table, - struct wim_lookup_table *dest_lookup_table, - struct list_head *lte_list_head) +static void +inode_move_ltes_to_table(struct wim_inode *inode, + struct wim_lookup_table *src_lookup_table, + struct wim_lookup_table *dest_lookup_table, + struct list_head *lte_list_head) { struct wim_lookup_table_entry *src_lte, *dest_lte; unsigned i; - struct wim_dentry *dentry; - - inode_for_each_dentry(dentry, inode) - dentry->refcnt++; for (i = 0; i <= inode->i_num_ads; i++) { src_lte = inode_stream_lte_unresolved(inode, i, src_lookup_table); @@ -78,7 +77,7 @@ static void inode_move_ltes_to_table(struct wim_inode *inode, list_del(next); dest_lte = container_of(next, struct wim_lookup_table_entry, - staging_list); + export_stream_list); dest_lte->part_number = 1; dest_lte->refcnt = 0; wimlib_assert(hashes_equal(dest_lte->hash, src_lte->hash)); @@ -90,23 +89,22 @@ static void inode_move_ltes_to_table(struct wim_inode *inode, } /* - * Copies an image, or all the images, from a WIM file, into another WIM file. + * Exports an image, or all the images, from a WIM file, into another WIM file. */ -WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim, - int src_image, - WIMStruct *dest_wim, - const tchar *dest_name, - const tchar *dest_description, - int export_flags, - WIMStruct **additional_swms, - unsigned num_additional_swms, - wimlib_progress_func_t progress_func) +WIMLIBAPI int +wimlib_export_image(WIMStruct *src_wim, + int src_image, + WIMStruct *dest_wim, + const tchar *dest_name, + const tchar *dest_description, + int export_flags, + WIMStruct **additional_swms, + unsigned num_additional_swms, + wimlib_progress_func_t progress_func) { int ret; - struct wim_security_data *sd; struct wim_lookup_table *joined_tab, *src_wim_tab_save; struct wim_image_metadata *src_imd; - struct hlist_node *cur_node; struct list_head lte_list_head; struct wim_inode *inode; @@ -152,7 +150,7 @@ WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim, additional_swms, num_additional_swms, progress_func); - if (ret != 0) + if (ret) return ret; } return 0; @@ -185,21 +183,28 @@ WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim, } ret = verify_swm_set(src_wim, additional_swms, num_additional_swms); - if (ret != 0) + if (ret) + return ret; + + ret = wim_checksum_unhashed_streams(src_wim); + if (ret) + return ret; + ret = wim_checksum_unhashed_streams(dest_wim); + if (ret) return ret; if (num_additional_swms) { ret = new_joined_lookup_table(src_wim, additional_swms, num_additional_swms, &joined_tab); - if (ret != 0) + if (ret) return ret; src_wim_tab_save = src_wim->lookup_table; src_wim->lookup_table = joined_tab; } ret = select_wim_image(src_wim, src_image); - if (ret != 0) { + if (ret) { ERROR("Could not select image %d from the WIM `%"TS"' " "to export it", src_image, src_wim->filename); goto out; @@ -208,42 +213,37 @@ WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim, /* Pre-allocate the new lookup table entries that will be needed. This * way, it's not possible to run out of memory part-way through * modifying the lookup table of the destination WIM. */ - INIT_LIST_HEAD(<e_list_head); for_lookup_table_entry(src_wim->lookup_table, lte_zero_out_refcnt, NULL); src_imd = wim_get_current_image_metadata(src_wim); - - hlist_for_each_entry(inode, cur_node, &src_imd->inode_list, i_hlist) { + INIT_LIST_HEAD(<e_list_head); + image_for_each_inode(inode, src_imd) { ret = inode_allocate_needed_ltes(inode, src_wim->lookup_table, dest_wim->lookup_table, <e_list_head); - if (ret != 0) + if (ret) goto out_free_ltes; } ret = xml_export_image(src_wim->wim_info, src_image, &dest_wim->wim_info, dest_name, dest_description); - if (ret != 0) + if (ret) goto out_free_ltes; - sd = src_imd->security_data; - ret = add_new_dentry_tree(dest_wim, src_imd->root_dentry, sd); - if (ret != 0) + ret = append_image_metadata(dest_wim, src_imd); + if (ret) goto out_xml_delete_image; - dest_wim->image_metadata[ - dest_wim->hdr.image_count - 1].inode_list = src_imd->inode_list; - if (src_imd->inode_list.first) - src_imd->inode_list.first->pprev = NULL; + /* The `struct image_metadata' is now referenced by both the @src_wim + * and the @dest_wim. */ + src_imd->refcnt++; + src_imd->modified = 1; /* All memory allocations have been taken care of, so it's no longer - * possible for this function to fail. Go ahead and increment the - * reference counts of the dentry tree and security data, then update - * the lookup table of the destination WIM and the boot index, if - * needed. */ - sd->refcnt++; - hlist_for_each_entry(inode, cur_node, &src_imd->inode_list, i_hlist) { + * possible for this function to fail. Go ahead and update the lookup + * table of the destination WIM and the boot index, if needed. */ + image_for_each_inode(inode, src_imd) { inode_move_ltes_to_table(inode, src_wim->lookup_table, dest_wim->lookup_table, @@ -251,19 +251,23 @@ WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim, } if (export_flags & WIMLIB_EXPORT_FLAG_BOOT) - wimlib_set_boot_idx(dest_wim, dest_wim->hdr.image_count); + dest_wim->hdr.boot_idx = dest_wim->hdr.image_count; + if (src_wim->hdr.flags & WIM_HDR_FLAG_RP_FIX) + { + /* Set the reparse point fixup flag on the destination WIM if + * the flag is set on the source WIM. */ + dest_wim->hdr.flags |= WIM_HDR_FLAG_RP_FIX; + } ret = 0; goto out; - out_xml_delete_image: - xml_delete_image(&dest_wim->wim_info, dest_wim->hdr.image_count); + xml_delete_image(&dest_wim->wim_info, dest_wim->hdr.image_count + 1); out_free_ltes: { struct wim_lookup_table_entry *lte, *tmp; - list_for_each_entry_safe(lte, tmp, <e_list_head, staging_list) + list_for_each_entry_safe(lte, tmp, <e_list_head, export_stream_list) free_lookup_table_entry(lte); } - out: if (num_additional_swms) { free_lookup_table(src_wim->lookup_table);