+ buf_len, dentry->reparse_tag);
+}
+
+static int dentry_set_symlink_buf(struct dentry *dentry,
+ struct lookup_table_entry *lte)
+{
+ struct ads_entry *ads_entries;
+
+ ads_entries = CALLOC(2, sizeof(struct ads_entry));
+ if (!ads_entries)
+ return WIMLIB_ERR_NOMEM;
+
+ wimlib_assert(dentry->num_ads == 0);
+ wimlib_assert(dentry->ads_entries == NULL);
+
+ ads_entries[1].lte = lte;
+
+ /*dentry_free_ads_entries(dentry);*/
+ dentry->num_ads = 2;
+ dentry->ads_entries = ads_entries;
+ return 0;
+}
+
+/*
+ * Sets @dentry 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 dentry_set_symlink(struct dentry *dentry, 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;
+ } 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->is_symlink = true;
+ lte->symlink_buf = symlink_buf;
+ lte->resource_entry.original_size = symlink_buf_len;
+ lte->resource_entry.size = symlink_buf_len;
+ copy_hash(lte->hash, symlink_buf_hash);
+ }
+
+ ret = dentry_set_symlink_buf(dentry, lte);
+
+ if (ret != 0)
+ goto out_free_lte;
+
+ dentry->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;