X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Finode.c;h=9eab0d7b534ecb2e3f29b90997ca700b6268c50b;hb=6f12ff5ab25f0935a78f4018a4540c4efb4c8e08;hp=e2f291631a043048273daf47fd1a958dc4209a2e;hpb=bde1c17816c7ed97c236158e2f1359bb34af08bf;p=wimlib diff --git a/src/inode.c b/src/inode.c index e2f29163..9eab0d7b 100644 --- a/src/inode.c +++ b/src/inode.c @@ -141,89 +141,51 @@ 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; + 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; @@ -238,8 +200,10 @@ do_inode_add_ads(struct wim_inode *inode, const void *stream_name, 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; @@ -247,26 +211,49 @@ do_inode_add_ads(struct wim_inode *inode, const void *stream_name, 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 @@ -307,10 +294,10 @@ 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; } @@ -327,8 +314,6 @@ inode_remove_ads(struct wim_inode *inode, u16 idx, 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); @@ -341,87 +326,6 @@ inode_remove_ads(struct wim_inode *inode, u16 idx, inode->i_num_ads--; } -bool -inode_has_unix_data(const struct wim_inode *inode) -{ - for (u16 i = 0; i < inode->i_num_ads; i++) - if (ads_entry_is_unix_data(&inode->i_ads_entries[i])) - return true; - return false; -} - -#ifndef __WIN32__ -int -inode_get_unix_data(const struct wim_inode *inode, - struct wimlib_unix_data *unix_data, - u16 *stream_idx_ret) -{ - const struct wim_ads_entry *ads_entry; - const struct wim_lookup_table_entry *lte; - size_t size; - int ret; - - wimlib_assert(inode->i_resolved); - - ads_entry = inode_get_ads_entry((struct wim_inode*)inode, - WIMLIB_UNIX_DATA_TAG, NULL); - if (ads_entry == NULL) - return NO_UNIX_DATA; - - if (stream_idx_ret) - *stream_idx_ret = ads_entry - inode->i_ads_entries; - - lte = ads_entry->lte; - if (lte == NULL) - return NO_UNIX_DATA; - - size = lte->size; - if (size != sizeof(struct wimlib_unix_data)) - return BAD_UNIX_DATA; - - ret = read_full_stream_into_buf(lte, unix_data); - if (ret) - return ret; - - if (unix_data->version != 0) - return BAD_UNIX_DATA; - return 0; -} - -int -inode_set_unix_data(struct wim_inode *inode, u16 uid, u16 gid, u16 mode, - struct wim_lookup_table *lookup_table, int which) -{ - struct wimlib_unix_data unix_data; - int ret; - bool have_good_unix_data = false; - bool have_unix_data = false; - u16 stream_idx; - - if (!(which & UNIX_DATA_CREATE)) { - ret = inode_get_unix_data(inode, &unix_data, &stream_idx); - if (ret == 0 || ret == BAD_UNIX_DATA || ret > 0) - have_unix_data = true; - if (ret == 0) - have_good_unix_data = true; - } - unix_data.version = 0; - if (which & UNIX_DATA_UID || !have_good_unix_data) - unix_data.uid = uid; - if (which & UNIX_DATA_GID || !have_good_unix_data) - unix_data.gid = gid; - if (which & UNIX_DATA_MODE || !have_good_unix_data) - unix_data.mode = mode; - ret = inode_add_ads_with_data(inode, WIMLIB_UNIX_DATA_TAG, - &unix_data, - sizeof(struct wimlib_unix_data), - lookup_table); - if (ret == 0 && have_unix_data) - inode_remove_ads(inode, stream_idx, lookup_table); - return ret; -} -#endif /* __WIN32__ */ - /* * Resolve an inode's lookup table entries. * @@ -737,14 +641,10 @@ read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode, 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;