/* API function documented in wimlib.h */ WIMLIBAPI int wimlib_resolve_image(WIMStruct *wim, const tchar *image_name_or_num) { tchar *p; long image; int i; if (!image_name_or_num || !*image_name_or_num) return WIMLIB_NO_IMAGE; if (!tstrcasecmp(image_name_or_num, T("all")) || !tstrcasecmp(image_name_or_num, T("*"))) return WIMLIB_ALL_IMAGES; image = tstrtol(image_name_or_num, &p, 10); if (p != image_name_or_num && *p == T('\0') && image > 0) { if (image > wim->hdr.image_count) return WIMLIB_NO_IMAGE; return image; } else { for (i = 1; i <= wim->hdr.image_count; i++) { if (!tstrcmp(image_name_or_num, wimlib_get_image_name(wim, i))) return i; } return WIMLIB_NO_IMAGE; } }
/* API function documented in wimlib.h */ 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) { int ret; int start_src_image; int end_src_image; int orig_dest_image_count; int image; bool all_images = (src_image == WIMLIB_ALL_IMAGES); /* 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)) return WIMLIB_ERR_METADATA_NOT_FOUND; if (all_images) { /* Multi-image export. */ if ((!(export_flags & WIMLIB_EXPORT_FLAG_NO_NAMES) && dest_name) || (!(export_flags & WIMLIB_EXPORT_FLAG_NO_DESCRIPTIONS) && dest_description)) { ERROR("Image name and description must be " "left NULL for multi-image export"); return WIMLIB_ERR_INVALID_PARAM; } start_src_image = 1; end_src_image = src_wim->hdr.image_count; } else { start_src_image = src_image; end_src_image = src_image; } orig_dest_image_count = dest_wim->hdr.image_count; /* Stream checksums must be known before proceeding. */ ret = wim_checksum_unhashed_streams(src_wim); if (ret) return ret; ret = wim_checksum_unhashed_streams(dest_wim); if (ret) return ret; /* Enable rollbacks */ for_lookup_table_entry(dest_wim->lookup_table, lte_set_not_exported, NULL); /* Export each requested image. */ for (src_image = start_src_image; src_image <= end_src_image; src_image++) { const tchar *next_dest_name, *next_dest_description; struct wim_image_metadata *src_imd; struct wim_inode *inode; /* Determine destination image name and description. */ if (export_flags & WIMLIB_EXPORT_FLAG_NO_NAMES) next_dest_name = T(""); else if (dest_name) next_dest_name = dest_name; else next_dest_name = wimlib_get_image_name(src_wim, src_image); if (export_flags & WIMLIB_EXPORT_FLAG_NO_DESCRIPTIONS) next_dest_description = T(""); else if (dest_description) next_dest_description = dest_description; else next_dest_description = wimlib_get_image_description(src_wim, src_image); /* Check for name conflict. */ if (wimlib_image_name_in_use(dest_wim, next_dest_name)) { ERROR("There is already an image named \"%"TS"\" " "in the destination WIM", next_dest_name); ret = WIMLIB_ERR_IMAGE_NAME_COLLISION; goto out_rollback; } /* Load metadata for source image into memory. */ ret = select_wim_image(src_wim, src_image); if (ret) goto out_rollback; src_imd = wim_get_current_image_metadata(src_wim); /* Iterate through inodes in the source image and export their * streams into the destination WIM. */ image_for_each_inode(inode, src_imd) { ret = inode_export_streams(inode, src_wim->lookup_table, dest_wim->lookup_table, export_flags & WIMLIB_EXPORT_FLAG_GIFT); if (ret) goto out_rollback; } /* Export XML information into the destination WIM. */ ret = xml_export_image(src_wim->wim_info, src_image, &dest_wim->wim_info, next_dest_name, next_dest_description); if (ret) goto out_rollback; /* Reference the source image metadata from the destination WIM. */ ret = append_image_metadata(dest_wim, src_imd); if (ret) goto out_rollback; src_imd->refcnt++; /* Lock the metadata into memory. XXX: need better solution for * this. */ src_imd->modified = 1; }
/* API function documented in wimlib.h */ 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) { int ret; int start_src_image; int end_src_image; int orig_dest_image_count; int image; bool all_images = (src_image == WIMLIB_ALL_IMAGES); /* 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 || !dest_wim) return WIMLIB_ERR_INVALID_PARAM; if (!wim_has_metadata(src_wim) || !wim_has_metadata(dest_wim)) return WIMLIB_ERR_METADATA_NOT_FOUND; if (all_images) { /* Multi-image export. */ if ((!(export_flags & WIMLIB_EXPORT_FLAG_NO_NAMES) && dest_name) || (!(export_flags & WIMLIB_EXPORT_FLAG_NO_DESCRIPTIONS) && dest_description)) { ERROR("Image name and description must be " "left NULL for multi-image export"); return WIMLIB_ERR_INVALID_PARAM; } start_src_image = 1; end_src_image = src_wim->hdr.image_count; } else { start_src_image = src_image; end_src_image = src_image; } orig_dest_image_count = dest_wim->hdr.image_count; /* We don't yet support having a single WIMStruct contain duplicate * 'image_metadata' structures, so we must forbid this from happening. * A duplication is possible if 'src_wim == dest_wim', if the same image * is exported to the same destination WIMStruct multiple times, or if * an image is exported in an A => B => A manner. */ for (src_image = start_src_image; src_image <= end_src_image; src_image++) { const struct wim_image_metadata *src_imd = src_wim->image_metadata[src_image - 1]; for (int i = 0; i < dest_wim->hdr.image_count; i++) if (dest_wim->image_metadata[i] == src_imd) return WIMLIB_ERR_DUPLICATE_EXPORTED_IMAGE; } /* Blob checksums must be known before proceeding. */ ret = wim_checksum_unhashed_blobs(src_wim); if (ret) return ret; ret = wim_checksum_unhashed_blobs(dest_wim); if (ret) return ret; /* Enable rollbacks */ for_blob_in_table(dest_wim->blob_table, blob_set_not_exported, NULL); /* Export each requested image. */ for (src_image = start_src_image; src_image <= end_src_image; src_image++) { const tchar *next_dest_name, *next_dest_description; struct wim_image_metadata *src_imd; struct wim_inode *inode; /* Determine destination image name and description. */ if (export_flags & WIMLIB_EXPORT_FLAG_NO_NAMES) next_dest_name = NULL; else if (dest_name) next_dest_name = dest_name; else next_dest_name = wimlib_get_image_name(src_wim, src_image); if (export_flags & WIMLIB_EXPORT_FLAG_NO_DESCRIPTIONS) next_dest_description = NULL; else if (dest_description) next_dest_description = dest_description; else next_dest_description = wimlib_get_image_description(src_wim, src_image); /* Check for name conflict. */ if (wimlib_image_name_in_use(dest_wim, next_dest_name)) { ERROR("There is already an image named \"%"TS"\" " "in the destination WIM", next_dest_name); ret = WIMLIB_ERR_IMAGE_NAME_COLLISION; goto out_rollback; } /* Load metadata for source image into memory. */ ret = select_wim_image(src_wim, src_image); if (ret) goto out_rollback; src_imd = wim_get_current_image_metadata(src_wim); /* Iterate through inodes in the source image and export their * blobs into the destination WIM. */ image_for_each_inode(inode, src_imd) { ret = inode_export_blobs(inode, src_wim->blob_table, dest_wim->blob_table, export_flags & WIMLIB_EXPORT_FLAG_GIFT); if (ret) goto out_rollback; } /* Export XML information into the destination WIM. */ ret = xml_export_image(src_wim->xml_info, src_image, dest_wim->xml_info, next_dest_name, next_dest_description, export_flags & WIMLIB_EXPORT_FLAG_WIMBOOT); if (ret) goto out_rollback; /* Reference the source image metadata from the destination WIM. */ ret = append_image_metadata(dest_wim, src_imd); if (ret) goto out_rollback; src_imd->refcnt++; }