-/*
- * Returns the alternate data stream entry belonging to @inode that has the
- * stream name @stream_name.
- */
-struct wim_ads_entry *
-inode_get_ads_entry(struct wim_inode *inode, const tchar *stream_name,
- u16 *idx_ret)
-{
- if (inode->i_num_ads == 0) {
- return NULL;
- } else {
- size_t stream_name_utf16le_nbytes;
- u16 i;
- struct wim_ads_entry *result;
-
- #if TCHAR_IS_UTF16LE
- const utf16lechar *stream_name_utf16le;
-
- stream_name_utf16le = stream_name;
- stream_name_utf16le_nbytes = tstrlen(stream_name) * sizeof(tchar);
- #else
- utf16lechar *stream_name_utf16le;
-
- {
- int ret = tstr_to_utf16le(stream_name,
- tstrlen(stream_name) *
- sizeof(tchar),
- &stream_name_utf16le,
- &stream_name_utf16le_nbytes);
- if (ret)
- return NULL;
- }
- #endif
- i = 0;
- result = NULL;
- do {
- if (ads_entry_has_name(&inode->i_ads_entries[i],
- stream_name_utf16le,
- stream_name_utf16le_nbytes))
- {
- if (idx_ret)
- *idx_ret = i;
- result = &inode->i_ads_entries[i];
- break;
- }
- } while (++i != inode->i_num_ads);
- #if !TCHAR_IS_UTF16LE
- FREE(stream_name_utf16le);
- #endif
- return result;
- }
-}
-
-static struct wim_ads_entry *
-do_inode_add_ads(struct wim_inode *inode, const void *stream_name,
- size_t stream_name_nbytes, bool is_utf16le)
-{
- u16 num_ads;
- struct wim_ads_entry *ads_entries;
- struct wim_ads_entry *new_entry;
-
- if (inode->i_num_ads >= 0xfffe) {
- ERROR("Too many alternate data streams in one inode!");
- return NULL;
- }
- num_ads = inode->i_num_ads + 1;
- ads_entries = REALLOC(inode->i_ads_entries,
- num_ads * sizeof(inode->i_ads_entries[0]));
- if (!ads_entries) {
- ERROR("Failed to allocate memory for new alternate data stream");
- return NULL;
- }
- inode->i_ads_entries = ads_entries;
-
- new_entry = &inode->i_ads_entries[num_ads - 1];
- if (init_ads_entry(new_entry, stream_name, stream_name_nbytes, is_utf16le))
- return NULL;
- new_entry->stream_id = inode->i_next_stream_id++;
- inode->i_num_ads = num_ads;
- return new_entry;
-}
-
-struct wim_ads_entry *
-inode_add_ads_utf16le(struct wim_inode *inode,
- const utf16lechar *stream_name,
- size_t stream_name_nbytes)
-{
- DEBUG("Add alternate data stream \"%"WS"\"", stream_name);
- return do_inode_add_ads(inode, stream_name, stream_name_nbytes, true);
-}
-
-/*
- * Add an alternate stream entry to a WIM inode and return a pointer to it, or
- * NULL if memory could not be allocated.
- */
-struct wim_ads_entry *
-inode_add_ads(struct wim_inode *inode, const tchar *stream_name)
-{
- DEBUG("Add alternate data stream \"%"TS"\"", stream_name);
- return do_inode_add_ads(inode, stream_name,
- tstrlen(stream_name) * sizeof(tchar),
- TCHAR_IS_UTF16LE);
-}
-
-static struct wim_lookup_table_entry *
-add_stream_from_data_buffer(const void *buffer, size_t size,
- struct wim_lookup_table *lookup_table)
-{
- u8 hash[SHA1_HASH_SIZE];
- struct wim_lookup_table_entry *lte, *existing_lte;
-
- sha1_buffer(buffer, size, hash);
- existing_lte = __lookup_resource(lookup_table, hash);
- if (existing_lte) {
- wimlib_assert(wim_resource_size(existing_lte) == size);
- lte = existing_lte;
- lte->refcnt++;
- } else {
- void *buffer_copy;
- lte = new_lookup_table_entry();
- if (!lte)
- return NULL;
- buffer_copy = memdup(buffer, size);
- if (!buffer_copy) {
- free_lookup_table_entry(lte);
- return NULL;
- }
- lte->resource_location = RESOURCE_IN_ATTACHED_BUFFER;
- lte->attached_buffer = buffer_copy;
- lte->resource_entry.original_size = size;
- copy_hash(lte->hash, hash);
- lookup_table_insert(lookup_table, lte);
- }
- return lte;
-}
-
-int
-inode_add_ads_with_data(struct wim_inode *inode, const tchar *name,
- const void *value, size_t size,
- struct wim_lookup_table *lookup_table)
-{
- struct wim_ads_entry *new_ads_entry;
-
- wimlib_assert(inode->i_resolved);
-
- new_ads_entry = inode_add_ads(inode, name);
- if (!new_ads_entry)
- return WIMLIB_ERR_NOMEM;
-
- new_ads_entry->lte = add_stream_from_data_buffer(value, size,
- lookup_table);
- if (!new_ads_entry->lte) {
- inode_remove_ads(inode, new_ads_entry - inode->i_ads_entries,
- lookup_table);
- return WIMLIB_ERR_NOMEM;
- }
- return 0;
-}
-
-/* Set the unnamed stream of a WIM inode, given a data buffer containing the
- * stream contents. */
-int
-inode_set_unnamed_stream(struct wim_inode *inode, const void *data, size_t len,
- struct wim_lookup_table *lookup_table)