{
const struct inode *inode = dentry->inode;
for (u16 i = 0; i < inode->num_ads; i++)
- length += ads_entry_total_length(inode->ads_entries[i]);
+ length += ads_entry_total_length(&inode->ads_entries[i]);
return (length + 7) & ~7;
}
inode->last_access_time = timespec_to_wim_timestamp(&stbuf->st_atim);
}
-
-/* Sets all the timestamp fields of the dentry to the current time. */
-void inode_update_all_timestamps(struct inode *inode)
+#ifdef WITH_FUSE
+/* Transfers file attributes from a struct inode to a `stat' buffer.
+ *
+ * The lookup table entry tells us which stream in the inode we are statting.
+ * For a named data stream, everything returned is the same as the unnamed data
+ * stream except possibly the size and block count. */
+int inode_to_stbuf(const struct inode *inode, struct lookup_table_entry *lte,
+ struct stat *stbuf)
{
- u64 now = get_wim_timestamp();
- inode->creation_time = now;
- inode->last_access_time = now;
- inode->last_write_time = now;
+ if (inode_is_symlink(inode))
+ stbuf->st_mode = S_IFLNK | 0777;
+ else if (inode_is_directory(inode))
+ stbuf->st_mode = S_IFDIR | 0755;
+ else
+ stbuf->st_mode = S_IFREG | 0644;
+
+ stbuf->st_ino = (ino_t)inode->ino;
+ stbuf->st_nlink = inode->link_count;
+ stbuf->st_uid = getuid();
+ stbuf->st_gid = getgid();
+
+ if (lte) {
+ if (lte->resource_location == RESOURCE_IN_STAGING_FILE) {
+ wimlib_assert(lte->staging_file_name);
+ struct stat native_stat;
+ if (stat(lte->staging_file_name, &native_stat) != 0) {
+ DEBUG("Failed to stat `%s': %m",
+ lte->staging_file_name);
+ return -errno;
+ }
+ stbuf->st_size = native_stat.st_size;
+ } else {
+ stbuf->st_size = wim_resource_size(lte);
+ }
+ } else {
+ stbuf->st_size = 0;
+ }
+
+ stbuf->st_atime = wim_timestamp_to_unix(inode->last_access_time);
+ stbuf->st_mtime = wim_timestamp_to_unix(inode->last_write_time);
+ stbuf->st_ctime = wim_timestamp_to_unix(inode->creation_time);
+ stbuf->st_blocks = (stbuf->st_size + 511) / 512;
+ return 0;
}
+#endif
+#ifdef WITH_FUSE
/* Returns the alternate data stream entry belonging to @inode that has the
* stream name @stream_name. */
struct ads_entry *inode_get_ads_entry(struct inode *inode,
u16 i = 0;
stream_name_len = strlen(stream_name);
do {
- if (ads_entry_has_name(inode->ads_entries[i],
+ if (ads_entry_has_name(&inode->ads_entries[i],
stream_name, stream_name_len))
{
if (idx_ret)
*idx_ret = i;
- return inode->ads_entries[i];
+ return &inode->ads_entries[i];
}
} while (++i != inode->num_ads);
}
return NULL;
}
+#endif
-static struct ads_entry *new_ads_entry(const char *name)
+static int init_ads_entry(struct ads_entry *ads_entry, const char *name)
{
- struct ads_entry *ads_entry = CALLOC(1, sizeof(struct ads_entry));
- if (!ads_entry)
- return NULL;
- if (name && *name) {
- if (change_ads_name(ads_entry, name)) {
- FREE(ads_entry);
- return NULL;
- }
+ int ret = 0;
+ memset(ads_entry, 0, sizeof(*ads_entry));
+ if (name && *name)
+ ret = change_ads_name(ads_entry, name);
+ return ret;
+}
+
+static void destroy_ads_entry(struct ads_entry *ads_entry)
+{
+ FREE(ads_entry->stream_name);
+ FREE(ads_entry->stream_name_utf8);
+}
+
+
+void inode_free_ads_entries(struct inode *inode)
+{
+ if (inode->ads_entries) {
+ for (u16 i = 0; i < inode->num_ads; i++)
+ destroy_ads_entry(&inode->ads_entries[i]);
+ FREE(inode->ads_entries);
}
- return ads_entry;
}
+#if defined(WITH_FUSE) || defined(WITH_NTFS_3G)
/*
* Add an alternate stream entry to an inode and return a pointer to it, or NULL
* if memory could not be allocated.
struct ads_entry *inode_add_ads(struct inode *inode, const char *stream_name)
{
u16 num_ads;
- struct ads_entry **ads_entries;
+ struct ads_entry *ads_entries;
struct ads_entry *new_entry;
if (inode->num_ads >= 0xfffe) {
}
inode->ads_entries = ads_entries;
- new_entry = new_ads_entry(stream_name);
- if (!new_entry)
+ new_entry = &inode->ads_entries[num_ads - 1];
+ if (init_ads_entry(new_entry, stream_name) != 0)
return NULL;
- inode->num_ads = num_ads;
- ads_entries[num_ads - 1] = new_entry;
#ifdef WITH_FUSE
new_entry->stream_id = inode->next_stream_id++;
#endif
return new_entry;
}
+#endif
+#ifdef WITH_FUSE
+/* Remove an alternate data stream from the inode */
+void inode_remove_ads(struct inode *inode, u16 idx,
+ struct lookup_table *lookup_table)
+{
+ struct ads_entry *ads_entry;
+ struct lookup_table_entry *lte;
+
+ ads_entry = &inode->ads_entries[idx];
+
+ wimlib_assert(ads_entry);
+ wimlib_assert(inode->resolved);
+
+ lte = ads_entry->lte;
+
+ if (lte)
+ lte_decrement_refcnt(lte, lookup_table);
+
+ destroy_ads_entry(ads_entry);
+
+ wimlib_assert(inode->num_ads);
+ memcpy(&inode->ads_entries[idx],
+ &inode->ads_entries[idx + 1],
+ (inode->num_ads - idx - 1) * sizeof(inode->ads_entries[0]));
+ inode->num_ads--;
+}
+#endif
/*
* Calls a function on all directory entries in a directory tree. It is called
}
for (u16 i = 0; i < inode->num_ads; i++) {
printf("[Alternate Stream Entry %u]\n", i);
- printf("Name = \"%s\"\n", inode->ads_entries[i]->stream_name_utf8);
+ printf("Name = \"%s\"\n", inode->ads_entries[i].stream_name_utf8);
printf("Name Length (UTF-16) = %u\n",
- inode->ads_entries[i]->stream_name_len);
+ inode->ads_entries[i].stream_name_len);
hash = inode_stream_hash(inode, i + 1);
if (hash) {
printf("Hash = 0x");
return __new_dentry_with_inode(name, false);
}
-void free_ads_entry(struct ads_entry *entry)
-{
- if (entry) {
- FREE(entry->stream_name);
- FREE(entry->stream_name_utf8);
- FREE(entry);
- }
-}
-
-void inode_free_ads_entries(struct inode *inode)
-{
- if (inode->ads_entries) {
- for (u16 i = 0; i < inode->num_ads; i++)
- free_ads_entry(inode->ads_entries[i]);
- FREE(inode->ads_entries);
- }
-}
/* Frees an inode. */
void free_inode(struct inode *inode)
free_dentry(dentry);
}
-#if 0
-/* Partically clones a dentry.
- *
- * Beware:
- * - memory for file names is not cloned (the pointers are all set to NULL
- * and the lengths are set to zero)
- * - next, prev, and children pointers and not touched
- */
-struct dentry *clone_dentry(struct dentry *old)
-{
- struct dentry *new = MALLOC(sizeof(struct dentry));
- if (!new)
- return NULL;
- memcpy(new, old, sizeof(struct dentry));
- new->file_name = NULL;
- new->file_name_len = 0;
- new->file_name_utf8 = NULL;
- new->file_name_utf8_len = 0;
- new->short_name = NULL;
- new->short_name_len = 0;
- return new;
-}
-#endif
-
/*
* This function is passed as an argument to for_dentry_in_tree_depth() in order
* to free a directory tree. __args is a pointer to a `struct free_dentry_args'.
u64 remaining_size)
{
u16 num_ads;
- struct ads_entry **ads_entries;
+ struct ads_entry *ads_entries;
int ret;
num_ads = inode->num_ads;
size_t utf8_len;
const u8 *p_save = p;
- cur_entry = new_ads_entry(NULL);
- if (!cur_entry) {
- ret = WIMLIB_ERR_NOMEM;
- goto out_free_ads_entries;
- }
-
- ads_entries[i] = cur_entry;
+ cur_entry = &ads_entries[i];
#ifdef WITH_FUSE
- ads_entries[i]->stream_id = i + 1;
+ ads_entries[i].stream_id = i + 1;
#endif
/* Read the base stream entry, excluding the stream name. */
return 0;
out_free_ads_entries:
for (u16 i = 0; i < num_ads; i++)
- free_ads_entry(ads_entries[i]);
+ destroy_ads_entry(&ads_entries[i]);
FREE(ads_entries);
return ret;
}
* read_ads_entries() for comments about the format of the on-disk
* alternate data stream entries. */
for (u16 i = 0; i < inode->num_ads; i++) {
- p = put_u64(p, ads_entry_total_length(inode->ads_entries[i]));
+ p = put_u64(p, ads_entry_total_length(&inode->ads_entries[i]));
p = put_u64(p, 0); /* Unused */
hash = inode_stream_hash(inode, i + 1);
p = put_bytes(p, SHA1_HASH_SIZE, hash);
- p = put_u16(p, inode->ads_entries[i]->stream_name_len);
- if (inode->ads_entries[i]->stream_name_len) {
- p = put_bytes(p, inode->ads_entries[i]->stream_name_len,
- (u8*)inode->ads_entries[i]->stream_name);
+ p = put_u16(p, inode->ads_entries[i].stream_name_len);
+ if (inode->ads_entries[i].stream_name_len) {
+ p = put_bytes(p, inode->ads_entries[i].stream_name_len,
+ (u8*)inode->ads_entries[i].stream_name);
p = put_u16(p, 0);
}
p = put_zeroes(p, (8 - (p - orig_p) % 8) % 8);
#include "sha1.h"
#include <string.h>
-
struct stat;
struct lookup_table;
struct WIMStruct;
+struct lookup_table_entry;
+struct wimlib_fd;
+struct inode;
+struct dentry;
/* Size of the struct dentry up to and including the file_name_len. */
#define WIM_DENTRY_DISK_SIZE 102
#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000
#define FILE_ATTRIBUTE_VIRTUAL 0x00010000
-struct lookup_table_entry;
/* Alternate data stream entry.
*
entry_1->stream_name_len) == 0;
}
-struct wimlib_fd;
-
-struct inode {
- /* Timestamps for the inode. The timestamps are the number of
- * 100-nanosecond intervals that have elapsed since 12:00 A.M., January
- * 1st, 1601, UTC. This is the same format used in NTFS inodes. */
- u64 creation_time;
- u64 last_access_time;
- u64 last_write_time;
-
- /* The file attributes associated with this inode. This is a bitwise OR
- * of the FILE_ATTRIBUTE_* flags. */
- u32 attributes;
-
- /* The index of the security descriptor in the WIM image's table of
- * security descriptors that contains this file's security information.
- * If -1, no security information exists for this file. */
- int32_t security_id;
-
- /* %true iff the inode's lookup table entries has been resolved (i.e.
- * the @lte field is valid, but the @hash field is not valid)
- *
- * (This is not an on-disk field.) */
- u8 resolved : 1;
-
- u8 verified : 1;
-
- u16 num_ads;
-
- /* A hash of the file's contents, or a pointer to the lookup table entry
- * for this dentry if the lookup table entries have been resolved.
- *
- * More specifically, this is for the un-named default file stream, as
- * opposed to the alternate (named) file streams, which may have their
- * own lookup table entries. */
- union {
- u8 hash[SHA1_HASH_SIZE];
- struct lookup_table_entry *lte;
- };
-
- /* Identity of a reparse point. See
- * http://msdn.microsoft.com/en-us/library/windows/desktop/aa365503(v=vs.85).aspx
- * for what a reparse point is. */
- u32 reparse_tag;
-
- u32 link_count;
-
- struct ads_entry **ads_entries;
-
- /* If the file is part of a hard link set, all the directory entries in
- * the set will share the same value for this field.
- *
- * Unfortunately, in some WIMs it is NOT the case that all dentries that
- * share this field are actually in the same hard link set, although the
- * WIMs that wimlib writes maintain this restriction. */
- u64 ino;
-
- struct list_head dentry_list;
- struct hlist_node hlist;
- char *extracted_file;
-
- struct dentry *children;
-
-#ifdef WITH_FUSE
- u16 num_opened_fds;
- u16 num_allocated_fds;
- struct wimlib_fd **fds;
- u32 next_stream_id;
-#endif
-};
-
-#define inode_for_each_dentry(dentry, inode) \
- list_for_each_entry((dentry), &(inode)->dentry_list, inode_dentry_list)
-
-#define inode_add_dentry(dentry, inode) \
- ({ \
- wimlib_assert((inode)->dentry_list.next != NULL); \
- list_add(&(dentry)->inode_dentry_list, &(inode)->dentry_list); \
- })
-
/*
* In-memory structure for a WIM directory entry (dentry). There is a directory
* tree for each image in the WIM.
*
- * Please note that this is a directory entry and not an inode. Since NTFS
- * allows hard links, it's possible for a NTFS inode to correspond to multiple
- * WIM dentries. The @hard_link field tells you the number of the NTFS inode
- * that the dentry corresponds to.
+ * Note that this is a directory entry and not an inode. Since NTFS allows hard
+ * links, it's possible for a NTFS inode to correspond to multiple WIM dentries.
+ * The hard_link field on the on-disk WIM dentry tells us the number of the NTFS
+ * inode that the dentry corresponds to.
*
* Unfortunately, WIM files do not have an analogue to an inode; instead certain
* information, such as file attributes, the security descriptor, and file
* streams is replicated in each hard-linked dentry, even though this
- * information really is associated with an inode.
+ * information really is associated with an inode. In-memory, we fix up this
+ * flaw by allocating a `struct inode' for each dentry that contains some of
+ * this duplicated information, then combining the inodes for each hard link
+ * group together.
*
- * Confusingly, it's also possible for stream information to be missing from a
- * dentry in a hard link set, in which case the stream information needs to be
- * gotten from one of the other dentries in the hard link set. In addition, it
- * is possible for dentries to have inconsistent security IDs, file attributes,
- * or file streams when they share the same hard link ID (don't even ask. I
- * hope that Microsoft may have fixed this problem, since I've only noticed it
- * in the 'install.wim' for Windows 7). For those dentries, we have to use the
- * conflicting fields to split up the hard link groups.
+ * Confusingly, it's possible for stream information to be missing from a dentry
+ * in a hard link set, in which case the stream information needs to be gotten
+ * from one of the other dentries in the hard link set. In addition, it is
+ * possible for dentries to have inconsistent security IDs, file attributes, or
+ * file streams when they share the same hard link ID (don't even ask. I hope
+ * that Microsoft may have fixed this problem, since I've only noticed it in the
+ * 'install.wim' for Windows 7). For those dentries, we have to use the
+ * conflicting fields to split up the hard link groups. (See fix_inodes() in
+ * hardlink.c).
*/
struct dentry {
/* The inode for this dentry */
*/
u64 length;
-
/* The offset, from the start of the uncompressed WIM metadata resource
* for this image, of this dentry's child dentries. 0 if the directory
* entry has no children, which is the case for regular files or reparse
* points. */
u64 subdir_offset;
-
- /* Although M$'s documentation does not tell you this, it seems that the
- * reparse_reserved field does not actually exist. So the hard_link
- * field directly follows the reparse_tag on disk. EXCEPT when the
- * dentry is actually a reparse point... well, just take a look at the
- * read_dentry() function. */
- //u32 reparse_reserved;
-
-
/* Length of short filename, in bytes, not including the terminating
* zero wide-character. */
u16 short_name_len;
* WIMStructs */
u32 refcnt;
- /* List of dentries in the hard link set */
+ /* List of dentries in the inode (hard link set) */
struct list_head inode_dentry_list;
+
union {
struct list_head tmp_list;
bool is_extracted;
};
};
+/*
+ * WIM inode.
+ *
+ * As mentioned above, in the WIM file that is no on-disk analogue of a real
+ * inode, as most of these fields are duplicated in the dentries.
+ */
+struct inode {
+ /* Timestamps for the inode. The timestamps are the number of
+ * 100-nanosecond intervals that have elapsed since 12:00 A.M., January
+ * 1st, 1601, UTC. This is the same format used in NTFS inodes. */
+ u64 creation_time;
+ u64 last_access_time;
+ u64 last_write_time;
+
+ /* The file attributes associated with this inode. This is a bitwise OR
+ * of the FILE_ATTRIBUTE_* flags. */
+ u32 attributes;
+
+ /* The index of the security descriptor in the WIM image's table of
+ * security descriptors that contains this file's security information.
+ * If -1, no security information exists for this file. */
+ int32_t security_id;
+
+ /* %true iff the inode's lookup table entries has been resolved (i.e.
+ * the @lte field is valid, but the @hash field is not valid)
+ *
+ * (This is not an on-disk field.) */
+ u8 resolved : 1;
+
+ /* %true iff verify_inode() has run on this dentry. */
+ u8 verified : 1;
+
+ /* Number of alternate data streams associated with this inode */
+ u16 num_ads;
+
+ /* A hash of the file's contents, or a pointer to the lookup table entry
+ * for this dentry if the lookup table entries have been resolved.
+ *
+ * More specifically, this is for the un-named default file stream, as
+ * opposed to the alternate (named) file streams, which may have their
+ * own lookup table entries. */
+ union {
+ u8 hash[SHA1_HASH_SIZE];
+ struct lookup_table_entry *lte;
+ };
+
+ /* Identity of a reparse point. See
+ * http://msdn.microsoft.com/en-us/library/windows/desktop/aa365503(v=vs.85).aspx
+ * for what a reparse point is. */
+ u32 reparse_tag;
+
+ /* Number of dentries that reference this inode */
+ u32 link_count;
+
+ /* Alternate data stream entries. */
+ struct ads_entry *ads_entries;
+
+ /* Inode number */
+ u64 ino;
+
+ /* List of dentries that reference this inode (there should be
+ * link_count of them) */
+ struct list_head dentry_list;
+ struct hlist_node hlist;
+ char *extracted_file;
+
+ /* If non-NULL, the children of this inode (implies the inode is a
+ * directory) */
+ struct dentry *children;
+
+#ifdef WITH_FUSE
+ /* wimfs file descriptors table for the inode */
+ u16 num_opened_fds;
+ u16 num_allocated_fds;
+ struct wimlib_fd **fds;
+
+ /* Next alternate data stream ID to be assigned */
+ u32 next_stream_id;
+#endif
+};
+
+#define inode_for_each_dentry(dentry, inode) \
+ list_for_each_entry((dentry), &(inode)->dentry_list, inode_dentry_list)
+
+#define inode_add_dentry(dentry, inode) \
+ ({ \
+ wimlib_assert((inode)->dentry_list.next != NULL); \
+ list_add(&(dentry)->inode_dentry_list, &(inode)->dentry_list); \
+ })
+
static inline bool dentry_is_extracted(const struct dentry *dentry)
{
return dentry->is_extracted;
}
-
extern struct ads_entry *inode_get_ads_entry(struct inode *inode,
const char *stream_name,
u16 *idx_ret);
extern struct ads_entry *inode_add_ads(struct inode *dentry,
const char *stream_name);
+extern void inode_remove_ads(struct inode *inode, u16 idx,
+ struct lookup_table *lookup_table);
+
extern const char *path_stream_name(const char *path);
extern u64 dentry_total_length(const struct dentry *dentry);
extern u64 dentry_correct_total_length(const struct dentry *dentry);
extern void stbuf_to_inode(const struct stat *stbuf, struct inode *inode);
+extern int inode_to_stbuf(const struct inode *inode,
+ struct lookup_table_entry *lte, struct stat *stbuf);
extern int for_dentry_in_tree(struct dentry *root,
int (*visitor)(struct dentry*, void*),
extern struct dentry *new_dentry_with_inode(const char *name);
extern struct dentry *new_dentry_with_timeless_inode(const char *name);
-extern void free_ads_entry(struct ads_entry *entry);
extern void inode_free_ads_entries(struct inode *inode);
extern struct inode *free_dentry(struct dentry *dentry);
extern void free_inode(struct inode *inode);
ref_2_hash = inode_stream_hash(ref_inode_2, i);
if (!hashes_equal(ref_1_hash, ref_2_hash))
return false;
- if (i && !ads_entries_have_same_name(ref_inode_1->ads_entries[i - 1],
- ref_inode_2->ads_entries[i - 1]))
+ if (i && !ads_entries_have_same_name(&ref_inode_1->ads_entries[i - 1],
+ &ref_inode_2->ads_entries[i - 1]))
return false;
}
hash = inode_stream_hash(inode, i);
if (!hashes_equal(ref_hash, hash) && !is_zero_hash(hash))
return false;
- if (i && !ads_entries_have_same_name(ref_inode->ads_entries[i - 1],
- inode->ads_entries[i - 1]))
+ if (i && !ads_entries_have_same_name(&ref_inode->ads_entries[i - 1],
+ &inode->ads_entries[i - 1]))
return false;
}
return true;
return NULL;
}
+#ifdef WITH_FUSE
/*
* Finds the dentry, lookup table entry, and stream index for a WIM file stream,
* given a path name.
*stream_idx_ret = stream_idx;
return 0;
}
+#endif
static void inode_resolve_ltes(struct inode *inode, struct lookup_table *table)
{
/* Resolve the alternate data streams */
for (u16 i = 0; i < inode->num_ads; i++) {
- struct ads_entry *cur_entry = inode->ads_entries[i];
-
+ struct ads_entry *cur_entry = &inode->ads_entries[i];
lte = __lookup_resource(table, cur_entry->hash);
cur_entry->lte = lte;
}
if (stream_idx == 0)
return inode->lte;
else
- return inode->ads_entries[stream_idx - 1]->lte;
+ return inode->ads_entries[stream_idx - 1].lte;
}
static inline struct lookup_table_entry *
else
return __lookup_resource(table,
inode->ads_entries[
- stream_idx - 1]->hash);
+ stream_idx - 1].hash);
}
/*
* Returns the lookup table entry for stream @stream_idx of the inode, where
if (stream_idx == 0)
return inode->hash;
else
- return inode->ads_entries[stream_idx - 1]->hash;
+ return inode->ads_entries[stream_idx - 1].hash;
}
if (stream_idx == 0)
return 0;
else
- return inode->ads_entries[stream_idx - 1]->stream_name_len;
+ return inode->ads_entries[stream_idx - 1].stream_name_len;
}
static inline struct lookup_table_entry *
put_dentry(dentry);
}
-/* Remove an alternate data stream from the inode */
-static void inode_remove_ads(struct inode *inode, u16 idx,
- struct lookup_table *lookup_table)
-{
- struct ads_entry *ads_entry;
- struct lookup_table_entry *lte;
-
- ads_entry = inode->ads_entries[idx];
-
- wimlib_assert(ads_entry);
-
- lte = ads_entry->lte;
-
- if (lte)
- lte_decrement_refcnt(lte, lookup_table);
-
- free_ads_entry(ads_entry);
-
- wimlib_assert(inode->num_ads);
- memcpy(&inode->ads_entries[idx],
- &inode->ads_entries[idx + 1],
- (inode->num_ads - idx - 1) * sizeof(inode->ads_entries[0]));
- inode->num_ads--;
-}
-
-/* Transfers file attributes from a struct inode to a `stat' buffer.
- *
- * The lookup table entry tells us which stream in the inode we are statting.
- * For a named data stream, everything returned is the same as the unnamed data
- * stream except possibly the size and block count. */
-int inode_to_stbuf(const struct inode *inode, struct lookup_table_entry *lte,
- struct stat *stbuf)
-{
- if (inode_is_symlink(inode))
- stbuf->st_mode = S_IFLNK | 0777;
- else if (inode_is_directory(inode))
- stbuf->st_mode = S_IFDIR | 0755;
- else
- stbuf->st_mode = S_IFREG | 0644;
-
- stbuf->st_ino = (ino_t)inode->ino;
- stbuf->st_nlink = inode->link_count;
- stbuf->st_uid = getuid();
- stbuf->st_gid = getgid();
-
- if (lte) {
- if (lte->resource_location == RESOURCE_IN_STAGING_FILE) {
- wimlib_assert(mount_flags & WIMLIB_MOUNT_FLAG_READWRITE);
- wimlib_assert(lte->staging_file_name);
- struct stat native_stat;
- if (stat(lte->staging_file_name, &native_stat) != 0) {
- DEBUG("Failed to stat `%s': %m",
- lte->staging_file_name);
- return -errno;
- }
- stbuf->st_size = native_stat.st_size;
- } else {
- stbuf->st_size = wim_resource_size(lte);
- }
- } else {
- stbuf->st_size = 0;
- }
-
- stbuf->st_atime = wim_timestamp_to_unix(inode->last_access_time);
- stbuf->st_mtime = wim_timestamp_to_unix(inode->last_write_time);
- stbuf->st_ctime = wim_timestamp_to_unix(inode->creation_time);
- stbuf->st_blocks = (stbuf->st_size + 511) / 512;
- return 0;
-}
-
/* Creates a new staging file and returns its file descriptor opened for
* writing.
*
inode->lte = new_lte;
else
for (u16 i = 0; i < inode->num_ads; i++)
- if (inode->ads_entries[i]->stream_id == stream_id)
- inode->ads_entries[i]->lte = new_lte;
+ if (inode->ads_entries[i].stream_id == stream_id)
+ inode->ads_entries[i].lte = new_lte;
lookup_table_insert(w->lookup_table, new_lte);
list_add(&new_lte->staging_list, &staging_list);
if (size == 0) {
needed_size = 0;
for (i = 0; i < inode->num_ads; i++)
- needed_size += inode->ads_entries[i]->stream_name_utf8_len + 6;
+ needed_size += inode->ads_entries[i].stream_name_utf8_len + 6;
return needed_size;
} else {
for (i = 0; i < inode->num_ads; i++) {
- needed_size = inode->ads_entries[i]->stream_name_utf8_len + 6;
+ needed_size = inode->ads_entries[i].stream_name_utf8_len + 6;
if (needed_size > size)
return -ERANGE;
p += sprintf(p, "user.%s",
- inode->ads_entries[i]->stream_name_utf8) + 1;
+ inode->ads_entries[i].stream_name_utf8) + 1;
size -= needed_size;
}
return p - list;
if (stream_idx == 0)
stream_id = 0;
else
- stream_id = inode->ads_entries[stream_idx - 1]->stream_id;
+ stream_id = inode->ads_entries[stream_idx - 1].stream_id;
/* The file resource may be in the staging directory (read-write mounts
* only) or in the WIM. If it's in the staging directory, we need to
if (stream_idx == 0)
stream_id = 0;
else
- stream_id = inode->ads_entries[stream_idx - 1]->stream_id;
+ stream_id = inode->ads_entries[stream_idx - 1].stream_id;
if (lte->resource_location == RESOURCE_IN_STAGING_FILE) {
wimlib_assert(lte->staging_file_name);
}
if (stream_idx == inode->num_ads)
break;
- stream_name = (ntfschar*)inode->ads_entries[stream_idx]->stream_name;
- stream_name_len = inode->ads_entries[stream_idx]->stream_name_len / 2;
+ stream_name = (ntfschar*)inode->ads_entries[stream_idx].stream_name;
+ stream_name_len = inode->ads_entries[stream_idx].stream_name_len / 2;
stream_idx++;
}
return ret;
return ret;
}
-/*#define HAVE_NTFS_INODE_FUNCTIONS*/
-
static int
apply_file_attributes_and_security_data(ntfs_inode *ni,
ntfs_inode *dir_ni,
DEBUG("Setting NTFS file attributes on `%s' to %#"PRIx32,
dentry->full_path_utf8, dentry->inode->attributes);
int ret;
-#ifdef HAVE_NTFS_INODE_FUNCTIONS
- ret = ntfs_set_inode_attributes(ni, dentry->inode->attributes);
-#else
struct SECURITY_CONTEXT ctx;
u32 attributes_le32;
attributes_le32 = cpu_to_le32(dentry->inode->attributes);
ni, dir_ni,
(const char*)&attributes_le32,
sizeof(u32), 0);
-#endif
if (ret != 0) {
ERROR("Failed to set NTFS file attributes on `%s'",
dentry->full_path_utf8);
DEBUG("Applying security descriptor %d to `%s'",
dentry->inode->security_id, dentry->full_path_utf8);
- #ifdef HAVE_NTFS_INODE_FUNCTIONS
- u32 selection = OWNER_SECURITY_INFORMATION |
- GROUP_SECURITY_INFORMATION |
- DACL_SECURITY_INFORMATION |
- SACL_SECURITY_INFORMATION;
- ret = ntfs_set_inode_security(ni, selection, descriptor);
- #else
ret = ntfs_xattr_system_setxattr(&ctx, XATTR_NTFS_ACL,
ni, dir_ni, descriptor,
sd->sizes[dentry->inode->security_id], 0);
- #endif
if (ret != 0) {
ERROR_WITH_ERRNO("Failed to set security data on `%s'",
#include <unistd.h>
#include <errno.h>
-#if 0
-extern int ntfs_get_inode_security(ntfs_inode *ni, u32 selection, char *buf,
- u32 buflen, u32 *psize);
-
-extern u32 ntfs_get_inode_attributes(ntfs_inode *ni);
-#endif
-
/* Structure that allows searching the security descriptors by SHA1 message
* digest. */
struct sd_set {
struct dentry *root;
mrec_flags = ni->mrec->flags;
-#ifdef HAVE_NTFS_INODE_FUNCTIONS
- attributes = ntfs_get_inode_attributes(ni);
-#else
struct SECURITY_CONTEXT ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.vol = ni->vol;
path);
return WIMLIB_ERR_NTFS_3G;
}
-#endif
if (exclude_path(path, config, false)) {
if (flags & WIMLIB_ADD_IMAGE_FLAG_VERBOSE) {
if (ret != 0)
return ret;
-#ifdef HAVE_NTFS_INODE_FUNCTIONS
- ret = ntfs_get_inode_security(ni,
- OWNER_SECURITY_INFORMATION |
- GROUP_SECURITY_INFORMATION |
- DACL_SECURITY_INFORMATION |
- SACL_SECURITY_INFORMATION,
- NULL, 0, &sd_size);
- char sd[sd_size];
- ret = ntfs_get_inode_security(ni,
- OWNER_SECURITY_INFORMATION |
- GROUP_SECURITY_INFORMATION |
- DACL_SECURITY_INFORMATION |
- SACL_SECURITY_INFORMATION,
- sd, sd_size, &sd_size);
- if (ret == 0) {
- ERROR_WITH_ERRNO("Failed to get security information from "
- "`%s'", path);
- ret = WIMLIB_ERR_NTFS_3G;
- } else {
- if (ret > 0) {
- /*print_security_descriptor(sd, sd_size);*/
- root->security_id = sd_set_add_sd(sd_set, sd, ret);
- if (root->security_id == -1) {
- ERROR("Out of memory");
- return WIMLIB_ERR_NOMEM;
- }
- DEBUG("Added security ID = %u for `%s'",
- root->security_id, path);
- } else {
- root->security_id = -1;
- DEBUG("No security ID for `%s'", path);
- }
- ret = 0;
- }
-#else
char _sd[1];
char *sd = _sd;
errno = 0;
root->inode->security_id = -1;
DEBUG("No security ID for `%s'", path);
}
-#endif
return ret;
}