+ return get_symlink_name(res_buf, wim_resource_size(lte), buf,
+ buf_len, inode->reparse_tag);
+}
+
+/*
+ * Sets @inode to be a symbolic link pointing to @target.
+ *
+ * A lookup table entry for the symbolic link data buffer is created and
+ * inserted into @lookup_table, unless there is an existing lookup table entry
+ * for the exact same data, in which its reference count is incremented.
+ *
+ * The lookup table entry is returned in @lte_ret.
+ *
+ * On failure @dentry and @lookup_table are not modified.
+ */
+int inode_set_symlink(struct inode *inode, const char *target,
+ struct lookup_table *lookup_table,
+ struct lookup_table_entry **lte_ret)
+
+{
+ int ret;
+ size_t symlink_buf_len;
+ struct lookup_table_entry *lte = NULL, *existing_lte;
+ u8 symlink_buf_hash[SHA1_HASH_SIZE];
+ void *symlink_buf;
+
+ symlink_buf = make_symlink_reparse_data_buf(target, &symlink_buf_len);
+ if (!symlink_buf)
+ return WIMLIB_ERR_NOMEM;
+
+ DEBUG("Made symlink reparse data buf (len = %zu, name len = %zu)",
+ symlink_buf_len, symlink_buf_len);
+
+ sha1_buffer(symlink_buf, symlink_buf_len, symlink_buf_hash);
+
+ existing_lte = __lookup_resource(lookup_table, symlink_buf_hash);
+
+ if (existing_lte) {
+ lte = existing_lte;
+ FREE(symlink_buf);
+ symlink_buf = NULL;
+ } else {
+ DEBUG("Creating new lookup table entry for symlink buf");
+ lte = new_lookup_table_entry();
+ if (!lte) {
+ ret = WIMLIB_ERR_NOMEM;
+ goto out_free_symlink_buf;
+ }
+ lte->resource_location = RESOURCE_IN_ATTACHED_BUFFER;
+ lte->attached_buffer = symlink_buf;
+ lte->resource_entry.original_size = symlink_buf_len;
+ lte->resource_entry.size = symlink_buf_len;
+ copy_hash(lte->hash, symlink_buf_hash);
+ }
+
+ inode->lte = lte;
+ inode->resolved = true;
+
+ DEBUG("Loaded symlink buf");
+
+ if (existing_lte)
+ lte->refcnt++;
+ else
+ lookup_table_insert(lookup_table, lte);
+ if (lte_ret)
+ *lte_ret = lte;
+ return 0;
+out_free_lte:
+ if (lte != existing_lte)
+ FREE(lte);
+out_free_symlink_buf:
+ FREE(symlink_buf);
+ return ret;