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;
+ int ret;
+ const utf16lechar *stream_name_utf16le;
+ size_t stream_name_utf16le_nbytes;
+ u16 i;
+ struct wim_ads_entry *result;
- if (stream_name[0] == T('\0'))
- return NULL;
+ if (inode->i_num_ads == 0)
+ return NULL;
- #if TCHAR_IS_UTF16LE
- const utf16lechar *stream_name_utf16le;
+ if (stream_name[0] == T('\0'))
+ return NULL;
- stream_name_utf16le = stream_name;
- stream_name_utf16le_nbytes = tstrlen(stream_name) * sizeof(tchar);
- #else
- utf16lechar *stream_name_utf16le;
+ ret = tstr_get_utf16le_and_len(stream_name, &stream_name_utf16le,
+ &stream_name_utf16le_nbytes);
+ if (ret)
+ return NULL;
+ i = 0;
+ result = NULL;
+ do {
+ if (ads_entry_has_name(&inode->i_ads_entries[i],
+ stream_name_utf16le,
+ stream_name_utf16le_nbytes,
+ default_ignore_case))
{
- int ret = tstr_to_utf16le(stream_name,
- tstrlen(stream_name) *
- sizeof(tchar),
- &stream_name_utf16le,
- &stream_name_utf16le_nbytes);
- if (ret)
- return NULL;
+ if (idx_ret)
+ *idx_ret = i;
+ result = &inode->i_ads_entries[i];
+ break;
}
- #endif
- i = 0;
- result = NULL;
- do {
- if (ads_entry_has_name(&inode->i_ads_entries[i],
- stream_name_utf16le,
- stream_name_utf16le_nbytes,
- default_ignore_case))
- {
- 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;
- }
-}
+ } while (++i != inode->i_num_ads);
-static int
-init_ads_entry(struct wim_ads_entry *ads_entry, const void *name,
- size_t name_nbytes, bool is_utf16le)
-{
- int ret = 0;
- memset(ads_entry, 0, sizeof(*ads_entry));
+ tstr_put_utf16le(stream_name_utf16le);
- if (is_utf16le) {
- utf16lechar *p = MALLOC(name_nbytes + sizeof(utf16lechar));
- if (p == NULL)
- return WIMLIB_ERR_NOMEM;
- memcpy(p, name, name_nbytes);
- p[name_nbytes / 2] = cpu_to_le16(0);
- ads_entry->stream_name = p;
- ads_entry->stream_name_nbytes = name_nbytes;
- } else {
- if (name && *(const tchar*)name != T('\0')) {
- ret = get_utf16le_string(name, &ads_entry->stream_name,
- &ads_entry->stream_name_nbytes);
- }
- }
- return ret;
+ 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)
+do_inode_add_ads(struct wim_inode *inode,
+ utf16lechar *stream_name, size_t stream_name_nbytes)
{
u16 num_ads;
struct wim_ads_entry *ads_entries;
struct wim_ads_entry *new_entry;
- wimlib_assert(stream_name_nbytes != 0);
-
if (inode->i_num_ads >= 0xfffe) {
ERROR("Too many alternate data streams in one inode!");
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;
+
+ memset(new_entry, 0, sizeof(struct wim_ads_entry));
+ new_entry->stream_name = stream_name;
+ new_entry->stream_name_nbytes = stream_name_nbytes;
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)
+ 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);
+ utf16lechar *dup = NULL;
+ struct wim_ads_entry *result;
+
+ if (stream_name_nbytes) {
+ dup = utf16le_dupz(stream_name, stream_name_nbytes);
+ if (!dup)
+ return NULL;
+ }
+
+ result = do_inode_add_ads(inode, dup, stream_name_nbytes);
+ if (!result)
+ FREE(dup);
+ return result;
}
/*
* Add an alternate stream entry to a WIM inode. On success, returns a pointer
* to the new entry; on failure, returns NULL.
- *
- * @stream_name must be a nonempty string.
*/
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);
+ utf16lechar *stream_name_utf16le = NULL;
+ size_t stream_name_utf16le_nbytes = 0;
+ int ret;
+ struct wim_ads_entry *result;
+
+ if (stream_name && *stream_name) {
+ ret = tstr_to_utf16le(stream_name,
+ tstrlen(stream_name) * sizeof(tchar),
+ &stream_name_utf16le,
+ &stream_name_utf16le_nbytes);
+ if (ret)
+ return NULL;
+ }
+
+ result = do_inode_add_ads(inode, stream_name_utf16le,
+ stream_name_utf16le_nbytes);
+ if (!result)
+ FREE(stream_name_utf16le);
+ return result;
}
int
inode_set_unnamed_stream(struct wim_inode *inode, const void *data, size_t len,
struct wim_lookup_table *lookup_table)
{
+ wimlib_assert(inode->i_resolved);
inode->i_lte = new_stream_from_data_buffer(data, len, lookup_table);
if (inode->i_lte == NULL)
return WIMLIB_ERR_NOMEM;
- inode->i_resolved = 1;
return 0;
}
ads_entry = &inode->i_ads_entries[idx];
- DEBUG("Remove alternate data stream \"%"WS"\"", ads_entry->stream_name);
-
lte = ads_entry->lte;
if (lte)
lte_decrement_refcnt(lte, lookup_table);
cur_entry->stream_name_nbytes > length)
goto out_invalid;
- cur_entry->stream_name = MALLOC(cur_entry->stream_name_nbytes + 2);
+ cur_entry->stream_name = utf16le_dupz(disk_entry->stream_name,
+ cur_entry->stream_name_nbytes);
if (cur_entry->stream_name == NULL)
goto out_of_memory;
-
- memcpy(cur_entry->stream_name,
- disk_entry->stream_name,
- cur_entry->stream_name_nbytes);
- cur_entry->stream_name[cur_entry->stream_name_nbytes / 2] = cpu_to_le16(0);
} else {
/* Mark inode as having weird stream entries. */
inode->i_canonical_streams = 0;
int
verify_inode(struct wim_inode *inode, const struct wim_security_data *sd)
{
- struct wim_dentry *dentry;
-
/* Check the security ID. -1 is valid and means "no security
* descriptor". Anything else has to be a valid index into the WIM
* image's security descriptors table. */
}
}
+void
+inode_unref_streams(struct wim_inode *inode,
+ struct wim_lookup_table *lookup_table)
+{
+ struct wim_lookup_table_entry *lte;
+ unsigned i;
+
+ for (i = 0; i <= inode->i_num_ads; i++) {
+ lte = inode_stream_lte(inode, i, lookup_table);
+ if (lte)
+ lte_decrement_refcnt(lte, lookup_table);
+ }
+}
+
int
init_inode_table(struct wim_inode_table *table, size_t capacity)
{