*/
/*
- * Copyright (C) 2013 Eric Biggers
+ * Copyright (C) 2013-2016 Eric Biggers
*
- * This file is part of wimlib, a library for working with WIM files.
+ * This file is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option) any
+ * later version.
*
- * wimlib is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option)
- * any later version.
- *
- * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * This file is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
- * You should have received a copy of the GNU General Public License
- * along with wimlib; if not, see http://www.gnu.org/licenses/.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this file; if not, see http://www.gnu.org/licenses/.
*/
#ifdef HAVE_CONFIG_H
#endif
#include "wimlib.h"
+#include "wimlib/blob_table.h"
#include "wimlib/dentry.h"
#include "wimlib/encoding.h"
-#include "wimlib/lookup_table.h"
#include "wimlib/metadata.h"
+#include "wimlib/object_id.h"
#include "wimlib/paths.h"
#include "wimlib/security.h"
#include "wimlib/timestamp.h"
#include "wimlib/util.h"
#include "wimlib/wim.h"
+static int
+stream_to_wimlib_stream_entry(const struct wim_inode *inode,
+ const struct wim_inode_stream *strm,
+ struct wimlib_stream_entry *wstream,
+ const struct blob_table *blob_table,
+ int flags)
+{
+ const struct blob_descriptor *blob;
+ const u8 *hash;
+
+ if (stream_is_named(strm)) {
+ size_t dummy;
+ int ret;
+
+ ret = utf16le_get_tstr(strm->stream_name,
+ utf16le_len_bytes(strm->stream_name),
+ &wstream->stream_name, &dummy);
+ if (ret)
+ return ret;
+ }
+
+ blob = stream_blob(strm, blob_table);
+ if (blob) {
+ blob_to_wimlib_resource_entry(blob, &wstream->resource);
+ } else if (!is_zero_hash((hash = stream_hash(strm)))) {
+ if (flags & WIMLIB_ITERATE_DIR_TREE_FLAG_RESOURCES_NEEDED)
+ return blob_not_found_error(inode, hash);
+ copy_hash(wstream->resource.sha1_hash, hash);
+ wstream->resource.is_missing = 1;
+ }
+ return 0;
+}
+
+static int
+get_default_stream_type(const struct wim_inode *inode)
+{
+ if (inode->i_attributes & FILE_ATTRIBUTE_ENCRYPTED)
+ return STREAM_TYPE_EFSRPC_RAW_DATA;
+ if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT)
+ return STREAM_TYPE_REPARSE_POINT;
+ return STREAM_TYPE_DATA;
+}
+
static int
init_wimlib_dentry(struct wimlib_dir_entry *wdentry, struct wim_dentry *dentry,
WIMStruct *wim, int flags)
int ret;
size_t dummy;
const struct wim_inode *inode = dentry->d_inode;
- struct wim_lookup_table_entry *lte;
- const u8 *hash;
+ const struct wim_inode_stream *strm;
struct wimlib_unix_data unix_data;
+ const void *object_id;
+ u32 object_id_len;
- ret = utf16le_get_tstr(dentry->file_name, dentry->file_name_nbytes,
+ ret = utf16le_get_tstr(dentry->d_name, dentry->d_name_nbytes,
&wdentry->filename, &dummy);
if (ret)
return ret;
- ret = utf16le_get_tstr(dentry->short_name, dentry->short_name_nbytes,
+ ret = utf16le_get_tstr(dentry->d_short_name, dentry->d_short_name_nbytes,
&wdentry->dos_name, &dummy);
if (ret)
return ret;
ret = calculate_dentry_full_path(dentry);
if (ret)
return ret;
- wdentry->full_path = dentry->_full_path;
+ wdentry->full_path = dentry->d_full_path;
for (struct wim_dentry *d = dentry; !dentry_is_root(d); d = d->d_parent)
wdentry->depth++;
- if (inode->i_security_id >= 0) {
+ if (inode_has_security_descriptor(inode)) {
struct wim_security_data *sd;
sd = wim_get_current_security_data(wim);
wdentry->unix_mode = unix_data.mode;
wdentry->unix_rdev = unix_data.rdev;
}
+ object_id = inode_get_object_id(inode, &object_id_len);
+ if (unlikely(object_id != NULL)) {
+ memcpy(&wdentry->object_id, object_id,
+ min(object_id_len, sizeof(wdentry->object_id)));
+ }
- lte = inode_unnamed_lte(inode, wim->lookup_table);
- if (lte) {
- lte_to_wimlib_resource_entry(lte, &wdentry->streams[0].resource);
- } else if (!is_zero_hash(hash = inode_unnamed_stream_hash(inode))) {
- if (flags & WIMLIB_ITERATE_DIR_TREE_FLAG_RESOURCES_NEEDED)
- return stream_not_found_error(inode, hash);
- copy_hash(wdentry->streams[0].resource.sha1_hash, hash);
- wdentry->streams[0].resource.is_missing = 1;
+ strm = inode_get_unnamed_stream(inode, get_default_stream_type(inode));
+ if (strm) {
+ ret = stream_to_wimlib_stream_entry(inode, strm,
+ &wdentry->streams[0],
+ wim->blob_table, flags);
+ if (ret)
+ return ret;
}
- for (unsigned i = 0; i < inode->i_num_ads; i++) {
- if (!ads_entry_is_named_stream(&inode->i_ads_entries[i]))
+ for (unsigned i = 0; i < inode->i_num_streams; i++) {
+
+ strm = &inode->i_streams[i];
+
+ if (!stream_is_named_data_stream(strm))
continue;
- lte = inode_stream_lte(inode, i + 1, wim->lookup_table);
- wdentry->num_named_streams++;
- if (lte) {
- lte_to_wimlib_resource_entry(lte, &wdentry->streams[
- wdentry->num_named_streams].resource);
- } else if (!is_zero_hash(hash = inode_stream_hash(inode, i + 1))) {
- if (flags & WIMLIB_ITERATE_DIR_TREE_FLAG_RESOURCES_NEEDED)
- return stream_not_found_error(inode, hash);
- copy_hash(wdentry->streams[
- wdentry->num_named_streams].resource.sha1_hash, hash);
- wdentry->streams[
- wdentry->num_named_streams].resource.is_missing = 1;
- }
- size_t dummy;
+ wdentry->num_named_streams++;
- ret = utf16le_get_tstr(inode->i_ads_entries[i].stream_name,
- inode->i_ads_entries[i].stream_name_nbytes,
- &wdentry->streams[
- wdentry->num_named_streams].stream_name,
- &dummy);
+ ret = stream_to_wimlib_stream_entry(inode, strm,
+ &wdentry->streams[
+ wdentry->num_named_streams],
+ wim->blob_table, flags);
if (ret)
return ret;
}
wdentry = CALLOC(1, sizeof(struct wimlib_dir_entry) +
- (1 + dentry->d_inode->i_num_ads) *
+ (1 + dentry->d_inode->i_num_streams) *
sizeof(struct wimlib_stream_entry));
if (wdentry == NULL)
goto out;
struct wim_dentry *child;
ret = 0;
- for_dentry_child(child, dentry) {
- ret = do_iterate_dir_tree(wim, child,
- flags & ~WIMLIB_ITERATE_DIR_TREE_FLAG_CHILDREN,
- cb, user_ctx);
- if (ret)
- break;
+ if (default_ignore_case) {
+ for_dentry_child_case_insensitive(child, dentry) {
+ ret = do_iterate_dir_tree(wim, child,
+ flags & ~WIMLIB_ITERATE_DIR_TREE_FLAG_CHILDREN,
+ cb, user_ctx);
+ if (ret)
+ break;
+ }
+ } else {
+ for_dentry_child(child, dentry) {
+ ret = do_iterate_dir_tree(wim, child,
+ flags & ~WIMLIB_ITERATE_DIR_TREE_FLAG_CHILDREN,
+ cb, user_ctx);
+ if (ret)
+ break;
+ }
}
}
out_free_wimlib_dentry:
+ FREE(dentry->d_full_path);
+ dentry->d_full_path = NULL;
free_wimlib_dentry(wdentry);
out:
return ret;
path = canonicalize_wim_path(_path);
if (path == NULL)
return WIMLIB_ERR_NOMEM;
+
+ ret = wim_checksum_unhashed_blobs(wim);
+ if (ret)
+ return ret;
+
struct image_iterate_dir_tree_ctx ctx = {
.path = path,
.flags = flags,