Exemplo n.º 1
0
static int
stream_to_wimlib_stream_entry(const struct wim_inode *inode,
			      const struct wim_inode_stream *strm,
			      struct wimlib_stream_entry *wstream,
			      const struct blob_table *blob_table,
			      int flags)
{
	const struct blob_descriptor *blob;
	const u8 *hash;

	if (stream_is_named(strm)) {
		size_t dummy;
		int ret;

		ret = utf16le_get_tstr(strm->stream_name,
				       utf16le_len_bytes(strm->stream_name),
				       &wstream->stream_name, &dummy);
		if (ret)
			return ret;
	}

	blob = stream_blob(strm, blob_table);
	if (blob) {
		blob_to_wimlib_resource_entry(blob, &wstream->resource);
	} else if (!is_zero_hash((hash = stream_hash(strm)))) {
		if (flags & WIMLIB_ITERATE_DIR_TREE_FLAG_RESOURCES_NEEDED)
			return blob_not_found_error(inode, hash);
		copy_hash(wstream->resource.sha1_hash, hash);
		wstream->resource.is_missing = 1;
	}
	return 0;
}
Exemplo n.º 2
0
static int
inode_export_streams(struct wim_inode *inode,
		     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_streams(inode);
	for (i = 0; i <= inode->i_num_ads; i++) {

		/* Retrieve SHA1 message digest of stream to export.  */
		hash = inode_stream_hash(inode, i);
		if (is_zero_hash(hash))  /* Empty stream?  */
			continue;

		/* Search for the stream (via SHA1 message digest) in the
		 * destination WIM.  */
		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_stream(src_lookup_table, hash);
			if (!src_lte)
				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;
			dest_lte->was_exported = 1;
			lookup_table_insert(dest_lookup_table, dest_lte);
		}

		/* Stream is present in destination WIM (either pre-existing,
		 * already exported, or just exported above).  Increment its
		 * reference count appropriately.   Note: we use 'refcnt' for
		 * the raw reference count, but 'out_refcnt' for references
		 * arising just from the export operation; this is used to roll
		 * back a failed export if needed.  */
		dest_lte->refcnt += inode->i_nlink;
		dest_lte->out_refcnt += inode->i_nlink;
	}
	return 0;
}
Exemplo n.º 3
0
static int
inode_export_blobs(struct wim_inode *inode, struct blob_table *src_blob_table,
		   struct blob_table *dest_blob_table, bool gift)
{
	unsigned i;
	const u8 *hash;
	struct blob_descriptor *src_blob, *dest_blob;

	for (i = 0; i < inode->i_num_streams; i++) {

		/* Retrieve SHA-1 message digest of blob to export.  */
		hash = stream_hash(&inode->i_streams[i]);
		if (is_zero_hash(hash))  /* Empty stream?  */
			continue;

		/* Search for the blob (via SHA-1 message digest) in the
		 * destination WIM.  */
		dest_blob = lookup_blob(dest_blob_table, hash);
		if (!dest_blob) {
			/* Blob not yet present in destination WIM.  Search for
			 * it in the source WIM, then export it into the
			 * destination WIM.  */
			src_blob = stream_blob(&inode->i_streams[i],
					       src_blob_table);
			if (!src_blob)
				return blob_not_found_error(inode, hash);

			if (gift) {
				dest_blob = src_blob;
				blob_table_unlink(src_blob_table, src_blob);
			} else {
				dest_blob = clone_blob_descriptor(src_blob);
				if (!dest_blob)
					return WIMLIB_ERR_NOMEM;
			}
			dest_blob->refcnt = 0;
			dest_blob->out_refcnt = 0;
			dest_blob->was_exported = 1;
			blob_table_insert(dest_blob_table, dest_blob);
		}

		/* Blob is present in destination WIM (either pre-existing,
		 * already exported, or just exported above).  Increment its
		 * reference count appropriately.   Note: we use 'refcnt' for
		 * the raw reference count, but 'out_refcnt' for references
		 * arising just from the export operation; this is used to roll
		 * back a failed export if needed.  */
		dest_blob->refcnt += inode->i_nlink;
		dest_blob->out_refcnt += inode->i_nlink;
	}
	return 0;
}