- * Currently, lookups of this type are only needed if FUSE is enabled. */
-int
-wim_pathname_to_stream(WIMStruct *wim,
- const tchar *path,
- int lookup_flags,
- struct wim_dentry **dentry_ret,
- struct wim_lookup_table_entry **lte_ret,
- u16 *stream_idx_ret)
-{
- struct wim_dentry *dentry;
- struct wim_lookup_table_entry *lte;
- u16 stream_idx;
- const tchar *stream_name = NULL;
- struct wim_inode *inode;
- tchar *p = NULL;
-
- if (lookup_flags & LOOKUP_FLAG_ADS_OK) {
- stream_name = path_stream_name(path);
- if (stream_name) {
- p = (tchar*)stream_name - 1;
- *p = T('\0');
- }
- }
-
- dentry = get_dentry(wim, path, WIMLIB_CASE_SENSITIVE);
- if (p)
- *p = T(':');
- if (!dentry)
- return -errno;
-
- inode = dentry->d_inode;
-
- if (!inode->i_resolved)
- if (inode_resolve_streams(inode, wim->lookup_table, false))
- return -EIO;
-
- if (!(lookup_flags & LOOKUP_FLAG_DIRECTORY_OK)
- && inode_is_directory(inode))
- return -EISDIR;
-
- if (stream_name) {
- struct wim_ads_entry *ads_entry;
- u16 ads_idx;
- ads_entry = inode_get_ads_entry(inode, stream_name,
- &ads_idx);
- if (ads_entry) {
- stream_idx = ads_idx + 1;
- lte = ads_entry->lte;
- goto out;
- } else {
- return -ENOENT;
- }
- } else {
- lte = inode_unnamed_stream_resolved(inode, &stream_idx);
- }
-out:
- if (dentry_ret)
- *dentry_ret = dentry;
- if (lte_ret)
- *lte_ret = lte;
- if (stream_idx_ret)
- *stream_idx_ret = stream_idx;
- return 0;
-}
-#endif /* WITH_FUSE */
-
-/* Prints the full path of a dentry. */
-int
-print_dentry_full_path(struct wim_dentry *dentry, void *_ignore)
-{
- int ret = calculate_dentry_full_path(dentry);
- if (ret)
- return ret;
- tprintf(T("%"TS"\n"), dentry->_full_path);
- return 0;
-}
-
-/* We want to be able to show the names of the file attribute flags that are
- * set. */
-struct file_attr_flag {
- u32 flag;
- const tchar *name;
-};
-struct file_attr_flag file_attr_flags[] = {
- {FILE_ATTRIBUTE_READONLY, T("READONLY")},
- {FILE_ATTRIBUTE_HIDDEN, T("HIDDEN")},
- {FILE_ATTRIBUTE_SYSTEM, T("SYSTEM")},
- {FILE_ATTRIBUTE_DIRECTORY, T("DIRECTORY")},
- {FILE_ATTRIBUTE_ARCHIVE, T("ARCHIVE")},
- {FILE_ATTRIBUTE_DEVICE, T("DEVICE")},
- {FILE_ATTRIBUTE_NORMAL, T("NORMAL")},
- {FILE_ATTRIBUTE_TEMPORARY, T("TEMPORARY")},
- {FILE_ATTRIBUTE_SPARSE_FILE, T("SPARSE_FILE")},
- {FILE_ATTRIBUTE_REPARSE_POINT, T("REPARSE_POINT")},
- {FILE_ATTRIBUTE_COMPRESSED, T("COMPRESSED")},
- {FILE_ATTRIBUTE_OFFLINE, T("OFFLINE")},
- {FILE_ATTRIBUTE_NOT_CONTENT_INDEXED,T("NOT_CONTENT_INDEXED")},
- {FILE_ATTRIBUTE_ENCRYPTED, T("ENCRYPTED")},
- {FILE_ATTRIBUTE_VIRTUAL, T("VIRTUAL")},
-};
-
-/* Prints a directory entry. @lookup_table is a pointer to the lookup table, if
- * available. If the dentry is unresolved and the lookup table is NULL, the
- * lookup table entries will not be printed. Otherwise, they will be. */
-int
-print_dentry(struct wim_dentry *dentry, void *lookup_table)
-{
- const u8 *hash;
- struct wim_lookup_table_entry *lte;
- const struct wim_inode *inode = dentry->d_inode;
- tchar buf[50];
-
- tprintf(T("[DENTRY]\n"));
- tprintf(T("Length = %"PRIu64"\n"), dentry->length);
- tprintf(T("Attributes = 0x%x\n"), inode->i_attributes);
- for (size_t i = 0; i < ARRAY_LEN(file_attr_flags); i++)
- if (file_attr_flags[i].flag & inode->i_attributes)
- tprintf(T(" FILE_ATTRIBUTE_%"TS" is set\n"),
- file_attr_flags[i].name);
- tprintf(T("Security ID = %d\n"), inode->i_security_id);
- tprintf(T("Subdir offset = %"PRIu64"\n"), dentry->subdir_offset);
-
- wim_timestamp_to_str(inode->i_creation_time, buf, sizeof(buf));
- tprintf(T("Creation Time = %"TS"\n"), buf);
-
- wim_timestamp_to_str(inode->i_last_access_time, buf, sizeof(buf));
- tprintf(T("Last Access Time = %"TS"\n"), buf);
-
- wim_timestamp_to_str(inode->i_last_write_time, buf, sizeof(buf));
- tprintf(T("Last Write Time = %"TS"\n"), buf);
-
- if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
- tprintf(T("Reparse Tag = 0x%"PRIx32"\n"), inode->i_reparse_tag);
- tprintf(T("Reparse Point Flags = 0x%"PRIx16"\n"),
- inode->i_not_rpfixed);
- tprintf(T("Reparse Point Unknown 2 = 0x%"PRIx32"\n"),
- inode->i_rp_unknown_2);
- }
- tprintf(T("Reparse Point Unknown 1 = 0x%"PRIx32"\n"),
- inode->i_rp_unknown_1);
- tprintf(T("Hard Link Group = 0x%"PRIx64"\n"), inode->i_ino);
- tprintf(T("Hard Link Group Size = %"PRIu32"\n"), inode->i_nlink);
- tprintf(T("Number of Alternate Data Streams = %hu\n"), inode->i_num_ads);
- if (dentry_has_long_name(dentry))
- wimlib_printf(T("Filename = \"%"WS"\"\n"), dentry->file_name);
- if (dentry_has_short_name(dentry))
- wimlib_printf(T("Short Name \"%"WS"\"\n"), dentry->short_name);
- if (dentry->_full_path)
- tprintf(T("Full Path = \"%"TS"\"\n"), dentry->_full_path);
-
- lte = inode_stream_lte(dentry->d_inode, 0, lookup_table);
- if (lte) {
- print_lookup_table_entry(lte, stdout);
- } else {
- hash = inode_stream_hash(inode, 0);
- if (hash) {
- tprintf(T("Hash = 0x"));
- print_hash(hash, stdout);
- tputchar(T('\n'));
- tputchar(T('\n'));
- }
- }
- for (u16 i = 0; i < inode->i_num_ads; i++) {
- tprintf(T("[Alternate Stream Entry %u]\n"), i);
- wimlib_printf(T("Name = \"%"WS"\"\n"),
- inode->i_ads_entries[i].stream_name);
- tprintf(T("Name Length (UTF16 bytes) = %hu\n"),
- inode->i_ads_entries[i].stream_name_nbytes);
- hash = inode_stream_hash(inode, i + 1);
- if (hash) {
- tprintf(T("Hash = 0x"));
- print_hash(hash, stdout);
- tputchar(T('\n'));
- }
- print_lookup_table_entry(inode_stream_lte(inode, i + 1, lookup_table),
- stdout);
- }
- return 0;
-}
-
-/* Initializations done on every `struct wim_dentry'. */
-static void
-dentry_common_init(struct wim_dentry *dentry)
-{
- memset(dentry, 0, sizeof(struct wim_dentry));
-}
-
-/* Creates an unlinked directory entry. */
-int