Exemplo n.º 1
0
Arquivo: wim.c Projeto: twwbond/wimlib
/* API function documented in wimlib.h  */
WIMLIBAPI void
wimlib_free(WIMStruct *wim)
{
    if (!wim)
        return;

    while (!list_empty(&wim->subwims)) {
        WIMStruct *subwim;

        subwim = list_entry(wim->subwims.next, WIMStruct, subwim_node);
        list_del(&subwim->subwim_node);
        wimlib_free(subwim);
    }

    if (filedes_valid(&wim->in_fd))
        filedes_close(&wim->in_fd);
    if (filedes_valid(&wim->out_fd))
        filedes_close(&wim->out_fd);

    free_blob_table(wim->blob_table);

    wimlib_free_decompressor(wim->decompressor);

    FREE(wim->filename);
    free_wim_info(wim->wim_info);
    if (wim->image_metadata) {
        for (unsigned i = 0; i < wim->hdr.image_count; i++)
            put_image_metadata(wim->image_metadata[i], NULL);
        FREE(wim->image_metadata);
    }
    FREE(wim);
}
Exemplo n.º 2
0
/* API function documented in wimlib.h  */
WIMLIBAPI int
wimlib_add_empty_image(WIMStruct *wim, const tchar *name, int *new_idx_ret)
{
	int ret;

	ret = can_modify_wim(wim);
	if (ret)
		return ret;

	if (!name)
		name = T("");

	if (wimlib_image_name_in_use(wim, name)) {
		ERROR("There is already an image named \"%"TS"\" in the WIM!",
		      name);
		return WIMLIB_ERR_IMAGE_NAME_COLLISION;
	}

	ret = add_empty_image_metadata(wim);
	if (ret)
		return ret;

	ret = xml_add_image(wim, name);
	if (ret) {
		put_image_metadata(wim->image_metadata[--wim->hdr.image_count],
				   NULL);
		return ret;
	}

	if (new_idx_ret)
		*new_idx_ret = wim->hdr.image_count;
	return 0;
}
Exemplo n.º 3
0
/* API function documented in wimlib.h  */
WIMLIBAPI int
wimlib_add_image_multisource(WIMStruct *wim,
			     const struct wimlib_capture_source *sources,
			     size_t num_sources,
			     const tchar *name,
			     const tchar *config_file,
			     int add_flags)
{
	int ret;
	struct wimlib_update_command *add_cmds;

	/* Make sure no reserved fields are set.  */
	for (size_t i = 0; i < num_sources; i++)
		if (sources[i].reserved != 0)
			return WIMLIB_ERR_INVALID_PARAM;

	/* Add the new image (initially empty).  */
	ret = wimlib_add_empty_image(wim, name, NULL);
	if (ret)
		return ret;

	/* Translate the "capture sources" into generic update commands.  */
	ret = WIMLIB_ERR_NOMEM;
	add_cmds = capture_sources_to_add_cmds(sources, num_sources,
					       add_flags, config_file);
	if (!add_cmds)
		goto out_delete_image;

	/* Delegate the work to wimlib_update_image().  */
	ret = wimlib_update_image(wim, wim->hdr.image_count, add_cmds,
				  num_sources, 0);
	FREE(add_cmds);
	if (ret)
		goto out_delete_image;

	/* If requested, set this image as the WIM's bootable image.  */
	if (add_flags & WIMLIB_ADD_FLAG_BOOT)
		wim->hdr.boot_idx = wim->hdr.image_count;

	/* If requested, mark new image as WIMBoot-compatible.  */
	if (add_flags & WIMLIB_ADD_FLAG_WIMBOOT)
		wim_info_set_wimboot(wim->wim_info, wim->hdr.image_count, true);

	return 0;

out_delete_image:
	/* Unsuccessful; rollback the WIM to its original state.  */

	/* wimlib_update_image() is now all-or-nothing, so no dentries remain
	 * and there's no need to pass the lookup table here.  */
	put_image_metadata(wim->image_metadata[wim->hdr.image_count - 1], NULL);

	xml_delete_image(&wim->wim_info, wim->hdr.image_count);
	wim->hdr.image_count--;
	return ret;
}
Exemplo n.º 4
0
/* Creates and appends a 'struct wim_image_metadata' for an empty image.
 *
 * The resulting image will be the last in the WIM, so its index will be
 * the new value of wim->hdr.image_count.  */
static int
add_empty_image_metadata(WIMStruct *wim)
{
	int ret;
	struct wim_lookup_table_entry *metadata_lte;
	struct wim_security_data *sd;
	struct wim_image_metadata *imd;

	/* Create lookup table entry for this metadata resource (for now really
	 * just a dummy entry).  */
	ret = WIMLIB_ERR_NOMEM;
	metadata_lte = new_lookup_table_entry();
	if (!metadata_lte)
		goto out;

	metadata_lte->flags = WIM_RESHDR_FLAG_METADATA;
	metadata_lte->unhashed = 1;

	/* Create empty security data (no security descriptors).  */
	sd = new_wim_security_data();
	if (!sd)
		goto out_free_metadata_lte;

	imd = new_image_metadata();
	if (!imd)
		goto out_free_security_data;

	/* A NULL root_dentry indicates a completely empty image, without even a
	 * root directory.  */
	imd->root_dentry = NULL;
	imd->metadata_lte = metadata_lte;
	imd->security_data = sd;
	imd->modified = 1;

	/* Append as next image index.  */
	ret = append_image_metadata(wim, imd);
	if (ret)
		put_image_metadata(imd, NULL);
	goto out;

out_free_security_data:
	free_wim_security_data(sd);
out_free_metadata_lte:
	free_lookup_table_entry(metadata_lte);
out:
	return ret;
}
Exemplo n.º 5
0
/* Internal method for single-image deletion.  This doesn't set the
 * image_deletion_occurred' flag on the WIMStruct.  */
int
delete_wim_image(WIMStruct *wim, int image)
{
	int ret;

	/* Load the metadata for the image to be deleted.  This is necessary
	 * because streams referenced by files in the image need to have their
	 * reference counts decremented.  */
	ret = select_wim_image(wim, image);
	if (ret)
		return ret;

	/* Release the reference to the image metadata and decrement reference
	 * counts on the streams referenced by files in the image.  */
	put_image_metadata(wim->image_metadata[image - 1], wim->lookup_table);

	/* Remove the empty slot from the image metadata array.  */
	memmove(&wim->image_metadata[image - 1], &wim->image_metadata[image],
		(wim->hdr.image_count - image) *
			sizeof(wim->image_metadata[0]));

	/* Decrement the image count. */
	--wim->hdr.image_count;

	/* Remove the image from the XML information. */
	xml_delete_image(&wim->wim_info, image);

	/* Fix the boot index. */
	if (wim->hdr.boot_idx == image)
		wim->hdr.boot_idx = 0;
	else if (wim->hdr.boot_idx > image)
		wim->hdr.boot_idx--;

	/* The image is no longer valid.  */
	wim->current_image = WIMLIB_NO_IMAGE;
	return 0;
}