+ buf_len, dentry->reparse_tag);
+}
+
+static int dentry_set_symlink_buf(struct dentry *dentry,
+ const u8 symlink_buf_hash[])
+{
+ struct ads_entry *ads_entries;
+
+ ads_entries = CALLOC(2, sizeof(struct ads_entry));
+ if (!ads_entries)
+ return WIMLIB_ERR_NOMEM;
+ memcpy(ads_entries[1].hash, symlink_buf_hash, WIM_HASH_SIZE);
+ dentry_free_ads_entries(dentry);
+ dentry->num_ads = 2;
+ dentry->ads_entries = ads_entries;
+ return 0;
+}
+
+int dentry_set_symlink(struct dentry *dentry, const char *target,
+ struct lookup_table *lookup_table)
+
+{
+ int ret;
+ size_t symlink_buf_len;
+ struct lookup_table_entry *lte = NULL, *existing_lte;
+ u8 symlink_buf_hash[WIM_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, ret);
+
+ sha1_buffer(symlink_buf, symlink_buf_len, symlink_buf_hash);
+
+ existing_lte = __lookup_resource(lookup_table, symlink_buf_hash);
+
+ if (existing_lte) {
+ existing_lte->refcnt++;
+ } 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;
+ memcpy(lte->hash, symlink_buf_hash, WIM_HASH_SIZE);
+ }
+
+ ret = dentry_set_symlink_buf(dentry, symlink_buf_hash);
+
+ if (ret != 0)
+ goto out_free_lte;
+
+ DEBUG("Loaded symlink buf");
+
+ if (!existing_lte)
+ lookup_table_insert(lookup_table, lte);
+ return 0;
+out_free_lte:
+ FREE(lte);
+out_free_symlink_buf:
+ FREE(symlink_buf);
+ return ret;