Exemple #1
0
void
deselect_current_wim_image(WIMStruct *wim)
{
    struct wim_image_metadata *imd;
    if (wim->current_image == WIMLIB_NO_IMAGE)
        return;
    imd = wim_get_current_image_metadata(wim);
    if (!imd->modified) {
        wimlib_assert(list_empty(&imd->unhashed_blobs));
        destroy_image_metadata(imd, NULL, false);
    }
    wim->current_image = WIMLIB_NO_IMAGE;
}
Exemple #2
0
static void
do_unlink(struct wim_dentry *subject, struct wim_dentry *parent,
	  struct wim_dentry **root_p)
{
	if (parent) {
		/* Unlink @subject from its @parent.  */
		wimlib_assert(subject->d_parent == parent);
		unlink_dentry(subject);
	} else {
		/* Unset @subject as the root of the image.  */
		*root_p = NULL;
	}
	subject->d_parent = subject;
}
Exemple #3
0
static void
do_link(struct wim_dentry *subject, struct wim_dentry *parent,
	struct wim_dentry **root_p)
{
	if (parent) {
		/* Link @subject to its @parent  */
		struct wim_dentry *existing;

		existing = dentry_add_child(parent, subject);
		wimlib_assert(!existing);
	} else {
		/* Set @subject as root of the image  */
		*root_p = subject;
	}
}
Exemple #4
0
static inline const tchar *
update_op_to_str(int op)
{
	switch (op) {
	case WIMLIB_UPDATE_OP_ADD:
		return T("add");
	case WIMLIB_UPDATE_OP_DELETE:
		return T("delete");
	case WIMLIB_UPDATE_OP_RENAME:
		return T("rename");
	default:
		wimlib_assert(0);
		return NULL;
	}
}
Exemple #5
0
void *
wimlib_aligned_malloc(size_t size, size_t alignment)
{
	wimlib_assert(alignment != 0 && is_power_of_2(alignment) &&
		      alignment <= 4096);

	const uintptr_t mask = alignment - 1;
	char *ptr = NULL;
	char *raw_ptr;

	raw_ptr = MALLOC(mask + sizeof(size_t) + size);
	if (raw_ptr) {
		ptr = (char *)raw_ptr + sizeof(size_t);
		ptr = (void *)(((uintptr_t)ptr + mask) & ~mask);
		*((size_t *)ptr - 1) = ptr - raw_ptr;
	}
	return ptr;
}
Exemple #6
0
/*
 * write_integrity_table():
 *
 * Writes a WIM integrity table (a list of SHA1 message digests of raw 10 MiB
 * chunks of the file).
 *
 * This function can optionally re-use entries from an older integrity table.
 * To do this, specify old_lookup_table_end and old_table.
 *
 * @wim:
 *	WIMStruct for the WIM file.  @wim->out_fd must be a seekable descriptor
 *	to the new WIM file, opened read-write, positioned at the location at
 *	which the integrity table is to be written.  Furthermore,
 *	@wim->hdr.integrity is expected to be a resource entry which will be set
 *	to the integrity table information on success.  In addition, if
 *	@old_lookup_table_end != 0, @wim->hdr.integrity must initially contain
 *	information about the old integrity table, and @wim->in_fd must be a
 *	seekable descriptor to the original WIM file opened for reading.
 *
 * @new_lookup_table_end:
 *	The offset of the byte directly following the lookup table in the WIM
 *	being written.
 *
 * @old_lookup_table_end:
 *	If nonzero, the offset of the byte directly following the old lookup
 *	table in the WIM.
 *
 * @old_table
 *	Pointer to the old integrity table read into memory, or NULL if not
 *	specified.
 */
int
write_integrity_table(WIMStruct *wim,
		      off_t new_lookup_table_end,
		      off_t old_lookup_table_end,
		      struct integrity_table *old_table)
{
	struct integrity_table *new_table;
	int ret;
	u32 new_table_size;

	DEBUG("Writing integrity table "
	      "(new_lookup_table_end=%"PRIu64", old_lookup_table_end=%"PRIu64")",
	      new_lookup_table_end, old_lookup_table_end);

	wimlib_assert(old_lookup_table_end <= new_lookup_table_end);

	ret = calculate_integrity_table(&wim->out_fd, new_lookup_table_end,
					old_table, old_lookup_table_end,
					&new_table, wim->progfunc, wim->progctx);
	if (ret)
		return ret;

	new_table_size = new_table->size;

	new_table->size        = cpu_to_le32(new_table->size);
	new_table->num_entries = cpu_to_le32(new_table->num_entries);
	new_table->chunk_size  = cpu_to_le32(new_table->chunk_size);

	ret = write_wim_resource_from_buffer(new_table,
					     new_table_size,
					     0,
					     &wim->out_fd,
					     WIMLIB_COMPRESSION_TYPE_NONE,
					     0,
					     &wim->hdr.integrity_table_reshdr,
					     NULL,
					     0);
	FREE(new_table);
	DEBUG("ret=%d", ret);
	return ret;
}
Exemple #7
0
void *
wimlib_aligned_malloc(size_t size, size_t alignment)
{
	u8 *raw_ptr;
	u8 *ptr;
	uintptr_t mask;

	wimlib_assert(alignment != 0 && is_power_of_2(alignment) &&
		      alignment <= 4096);
	mask = alignment - 1;

	raw_ptr = MALLOC(size + alignment - 1 + sizeof(size_t));
	if (!raw_ptr)
		return NULL;

	ptr = (u8 *)raw_ptr + sizeof(size_t);
	while ((uintptr_t)ptr & mask)
		ptr++;
	*((size_t *)ptr - 1) = (ptr - raw_ptr);

	return ptr;
}
Exemple #8
0
static int
do_attach_branch(struct wim_dentry *branch, const utf16lechar *target,
		 struct update_command_journal *j,
		 int add_flags, wimlib_progress_func_t progfunc, void *progctx)
{
	struct wim_dentry *parent;
	struct wim_dentry *existing;
	const utf16lechar empty_name[1] = {0};
	const utf16lechar *cur_component_name;
	size_t cur_component_nbytes;
	const utf16lechar *next_component_name;
	int ret;

	/* Attempt to create root directory before proceeding to the "real"
	 * first component  */
	parent = NULL;
	existing = *j->root_p;
	cur_component_name = empty_name;
	cur_component_nbytes = 0;

	/* Skip leading slashes  */
	next_component_name = target;
	while (*next_component_name == cpu_to_le16(WIM_PATH_SEPARATOR))
		next_component_name++;

	while (*next_component_name) { /* While not the last component ... */
		const utf16lechar *end;

		if (existing) {
			/* Descend into existing directory  */
			if (!dentry_is_directory(existing)) {
				ERROR("\"%"TS"\" in the WIM image "
				      "is not a directory!",
				      dentry_full_path(existing));
				return WIMLIB_ERR_NOTDIR;
			}
		} else {
			/* A parent directory of the target didn't exist.  Make
			 * the way by creating a filler directory.  */
			struct wim_dentry *filler;

			ret = new_filler_directory(&filler);
			if (ret)
				return ret;
			ret = dentry_set_name_utf16le(filler,
						      cur_component_name,
						      cur_component_nbytes);
			if (ret) {
				free_dentry(filler);
				return ret;
			}
			ret = journaled_link(j, filler, parent);
			if (ret) {
				free_dentry(filler);
				return ret;
			}
			existing = filler;
		}

		/* Advance to next component  */

		cur_component_name = next_component_name;
		end = cur_component_name + 1;
		while (*end && *end != cpu_to_le16(WIM_PATH_SEPARATOR))
			end++;

		next_component_name = end;
		if (*end) {
			/* There will still be more components after this.  */
			do {
			} while (*++next_component_name == cpu_to_le16(WIM_PATH_SEPARATOR));
			wimlib_assert(*next_component_name);  /* No trailing slashes  */
		} else {
			/* This will be the last component  */
			next_component_name = end;
		}
		parent = existing;
		cur_component_nbytes = (end - cur_component_name) * sizeof(utf16lechar);
		existing = get_dentry_child_with_utf16le_name(
					parent,
					cur_component_name,
					cur_component_nbytes,
					WIMLIB_CASE_PLATFORM_DEFAULT);
	}

	/* Last component  */
	if (existing) {
		return handle_conflict(branch, existing, j, add_flags,
				       progfunc, progctx);
	} else {
		return journaled_link(j, branch, parent);
	}
}
static int
prepare_metadata_resource(WIMStruct *wim, int image,
			  u8 **buf_ret, size_t *len_ret)
{
	u8 *buf;
	u8 *p;
	int ret;
	u64 subdir_offset;
	struct wim_dentry *root;
	size_t len;
	struct wim_security_data *sd;
	struct wim_image_metadata *imd;

	ret = select_wim_image(wim, image);
	if (ret)
		return ret;

	imd = wim->image_metadata[image - 1];

	root = imd->root_dentry;
	sd = imd->security_data;

	if (!root) {
		/* Empty image; create a dummy root.  */
		ret = new_filler_directory(&root);
		if (ret)
			return ret;
		imd->root_dentry = root;
	}

	/* The offset of the first child of the root dentry is equal to the
	 * total length of the security data, plus the total length of the root
	 * dentry, plus 8 bytes for an end-of-directory entry following the root
	 * dentry (shouldn't really be needed, but just in case...)  */
	recalculate_security_data_length(sd);
	subdir_offset = sd->total_length + dentry_out_total_length(root) + 8;

	/* Calculate the subdirectory offsets for the entire dentry tree.  */
	calculate_subdir_offsets(root, &subdir_offset);

	/* Total length of the metadata resource (uncompressed).  */
	len = subdir_offset;

	/* Allocate a buffer to contain the uncompressed metadata resource.  */
	buf = NULL;
	if (likely(len == subdir_offset))
		buf = MALLOC(len);
	if (!buf) {
		ERROR("Failed to allocate %"PRIu64" bytes for "
		      "metadata resource", subdir_offset);
		return WIMLIB_ERR_NOMEM;
	}

	/* Write the security data into the resource buffer.  */
	p = write_wim_security_data(sd, buf);

	/* Write the dentry tree into the resource buffer.  */
	p = write_dentry_tree(root, p);

	/* We MUST have exactly filled the buffer; otherwise we calculated its
	 * size incorrectly or wrote the data incorrectly.  */
	wimlib_assert(p - buf == len);

	*buf_ret = buf;
	*len_ret = len;
	return 0;
}