/* Return %true iff the alternate data stream entry @entry has the UTF-8 stream
* name @name that has length @name_len bytes. */
-static inline bool ads_entry_has_name(const struct ads_entry *entry,
+static inline bool ads_entry_has_name(const struct wim_ads_entry *entry,
const char *name, size_t name_len)
{
if (entry->stream_name_utf8_len != name_len)
/*
* Changes the name of an alternate data stream */
-static int change_ads_name(struct ads_entry *entry, const char *new_name)
+static int change_ads_name(struct wim_ads_entry *entry, const char *new_name)
{
return get_names(&entry->stream_name, &entry->stream_name_utf8,
&entry->stream_name_len,
/* Returns the total length of a WIM alternate data stream entry on-disk,
* including the stream name, the null terminator, AND the padding after the
* entry to align the next ADS entry or dentry on an 8-byte boundary. */
-static u64 ads_entry_total_length(const struct ads_entry *entry)
+static u64 ads_entry_total_length(const struct wim_ads_entry *entry)
{
u64 len = WIM_ADS_ENTRY_DISK_SIZE;
if (entry->stream_name_len)
}
-static int init_ads_entry(struct ads_entry *ads_entry, const char *name)
+static int init_ads_entry(struct wim_ads_entry *ads_entry, const char *name)
{
int ret = 0;
memset(ads_entry, 0, sizeof(*ads_entry));
return ret;
}
-static void destroy_ads_entry(struct ads_entry *ads_entry)
+static void destroy_ads_entry(struct wim_ads_entry *ads_entry)
{
FREE(ads_entry->stream_name);
FREE(ads_entry->stream_name_utf8);
}
#ifdef WITH_FUSE
-/*
- * Unlink a dentry from the directory tree.
- *
- * Note: This merely removes it from the in-memory tree structure.
- */
+/* Unlink a WIM dentry from the directory entry tree. */
void unlink_dentry(struct wim_dentry *dentry)
{
struct wim_dentry *parent = dentry->parent;
#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 wim_inode *inode,
+/*
+ * Returns the alternate data stream entry belonging to @inode that has the
+ * stream name @stream_name.
+ */
+struct wim_ads_entry *inode_get_ads_entry(struct wim_inode *inode,
const char *stream_name,
u16 *idx_ret)
{
#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.
+ * Add an alternate stream entry to a WIM inode and return a pointer to it, or
+ * NULL if memory could not be allocated.
*/
-struct ads_entry *inode_add_ads(struct wim_inode *inode, const char *stream_name)
+struct wim_ads_entry *inode_add_ads(struct wim_inode *inode, const char *stream_name)
{
u16 num_ads;
- struct ads_entry *ads_entries;
- struct ads_entry *new_entry;
+ struct wim_ads_entry *ads_entries;
+ struct wim_ads_entry *new_entry;
DEBUG("Add alternate data stream \"%s\"", stream_name);
#endif
#ifdef WITH_FUSE
-/* Remove an alternate data stream from the inode */
+/* Remove an alternate data stream from a WIM inode */
void inode_remove_ads(struct wim_inode *inode, u16 idx,
struct wim_lookup_table *lookup_table)
{
- struct ads_entry *ads_entry;
+ struct wim_ads_entry *ads_entry;
struct wim_lookup_table_entry *lte;
wimlib_assert(idx < inode->i_num_ads);
/*
- * Reads the alternate data stream entries for a dentry.
+ * Reads the alternate data stream entries of a WIM dentry.
*
* @p: Pointer to buffer that starts with the first alternate stream entry.
*
*
* The format of the on-disk alternate stream entries is as follows:
*
- * struct ads_entry_on_disk {
+ * struct wim_ads_entry_on_disk {
* u64 length; // Length of the entry, in bytes. This includes
* all fields (including the stream name and
* null terminator if present, AND the padding!).
* In addition, the entries are 8-byte aligned.
*
* Return 0 on success or nonzero on failure. On success, inode->i_ads_entries
- * is set to an array of `struct ads_entry's of length inode->i_num_ads. On
+ * is set to an array of `struct wim_ads_entry's of length inode->i_num_ads. On
* failure, @inode is not modified.
*/
static int read_ads_entries(const u8 *p, struct wim_inode *inode,
u64 remaining_size)
{
u16 num_ads;
- struct ads_entry *ads_entries;
+ struct wim_ads_entry *ads_entries;
int ret;
num_ads = inode->i_num_ads;
}
for (u16 i = 0; i < num_ads; i++) {
- struct ads_entry *cur_entry;
+ struct wim_ads_entry *cur_entry;
u64 length;
u64 length_no_padding;
u64 total_length;
}
/*
- * Reads a directory entry, including all alternate data stream entries that
+ * Reads a WIM directory entry, including all alternate data stream entries that
* follow it, from the WIM image's metadata resource.
*
* @metadata_resource: Buffer containing the uncompressed metadata resource.
*
* We read this from disk in the read_ads_entries() function; see that function
* for more explanation. */
-struct ads_entry {
+struct wim_ads_entry {
union {
/* SHA-1 message digest of stream contents */
u8 hash[SHA1_HASH_SIZE];
};
-static inline bool ads_entries_have_same_name(const struct ads_entry *entry_1,
- const struct ads_entry *entry_2)
+static inline bool ads_entries_have_same_name(const struct wim_ads_entry *entry_1,
+ const struct wim_ads_entry *entry_2)
{
if (entry_1->stream_name_len != entry_2->stream_name_len)
return false;
*
* 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.
+ * The hard link group ID field of the on-disk WIM dentry tells us the number of
+ * the NTFS inode that the dentry corresponds to (and this gets placed in
+ * d_inode->i_ino).
*
* Unfortunately, WIM files do not have an analogue to an inode; instead certain
* information, such as file attributes, the security descriptor, and file
* 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).
+ * conflicting fields to split up the hard link groups. (See
+ * dentry_tree_fix_inodes() in hardlink.c).
*/
struct wim_dentry {
/* Byte 0 */
u32 i_nlink;
/* Alternate data stream entries. */
- struct ads_entry *i_ads_entries;
+ struct wim_ads_entry *i_ads_entries;
/* Inode number */
u64 i_ino;
extern int set_dentry_name(struct wim_dentry *dentry, const char *new_name);
extern struct wim_dentry *get_dentry(struct WIMStruct *w, const char *path);
+
extern struct wim_inode *wim_pathname_to_inode(struct WIMStruct *w,
- const char *path);
-extern struct wim_dentry *get_dentry_child_with_name(const struct wim_dentry *dentry,
- const char *name);
-extern struct wim_dentry *get_parent_dentry(struct WIMStruct *w, const char *path);
+ const char *path);
+
+extern struct wim_dentry *
+get_dentry_child_with_name(const struct wim_dentry *dentry, const char *name);
+
+extern struct wim_dentry *get_parent_dentry(struct WIMStruct *w,
+ const char *path);
extern int print_dentry(struct wim_dentry *dentry, void *lookup_table);
extern int print_dentry_full_path(struct wim_dentry *entry, void *ignore);
extern bool dentry_add_child(struct wim_dentry * restrict parent,
struct wim_dentry * restrict child);
-extern struct ads_entry *inode_get_ads_entry(struct wim_inode *inode,
- const char *stream_name,
- u16 *idx_ret);
-extern struct ads_entry *inode_add_ads(struct wim_inode *dentry,
- const char *stream_name);
+extern struct wim_ads_entry *inode_get_ads_entry(struct wim_inode *inode,
+ const char *stream_name,
+ u16 *idx_ret);
+
+extern struct wim_ads_entry *inode_add_ads(struct wim_inode *dentry,
+ const char *stream_name);
extern void inode_remove_ads(struct wim_inode *inode, u16 idx,
struct wim_lookup_table *lookup_table);
extern int read_dentry_tree(const u8 metadata_resource[],
- u64 metadata_resource_len, struct wim_dentry *dentry);
+ u64 metadata_resource_len,
+ struct wim_dentry *dentry);
extern u8 *write_dentry_tree(const struct wim_dentry *tree, u8 *p);
*
* - Groups we create ourselves by splitting a nominal inode due to
* inconsistencies in the dentries. These inodes will share a inode
- * ID with some other inode until assign_inode_numbers() is called.
+ * number with some other inode until assign_inode_numbers() is
+ * called.
*/
struct hlist_head extra_inodes;
};
/*
* dentry_tree_fix_inodes():
*
- * This function takes as input a tree of WIM dentries that has a different
- * inode associated with every dentry. Sets of dentries that share the same
- * inode (a.k.a. hard link groups) are built using the i_ino field of each
- * inode, then the link count and alias list for one inode in each set is set
- * correctly and the unnecessary struct wim_inode's freed. The effect is to
- * correctly associate exactly one struct wim_inode with each original inode,
- * regardless of how many dentries are aliases for that inode.
+ * This function takes as input a tree of WIM dentries that initially has a
+ * different inode associated with each dentry. Sets of dentries that should
+ * share the same inode (a.k.a. hard link groups) are built using the i_ino
+ * field of each inode, then the link count and alias list for one inode in each
+ * set is set correctly and the unnecessary struct wim_inode's freed. The
+ * effect is to correctly associate exactly one struct wim_inode with each
+ * original inode, regardless of how many dentries are aliases for that inode.
*
* The special inode number of 0 indicates that the dentry is in a hard link
* group by itself, and therefore has a 'struct wim_inode' with i_nlink=1 to
* This function also checks the dentries in each hard link group for
* consistency. In some WIMs, such as install.wim for some versions of Windows
* 7, dentries can share the same hard link group ID but not actually be hard
- * linked to each other (e.g. to having different data streams). This should be
- * an error, but this case needs be handled. So, each "nominal" inode (the
- * inode based on the inode numbers provided in the WIM) is examined for
- * consistency and may be split into multiple "true" inodes that are maximally
- * sized consistent sets of dentries.
+ * linked to each other (based on conflicting information, such as file
+ * contents). This should be an error, but this case needs be handled. So,
+ * each "nominal" inode (the inode based on the inode numbers provided in the
+ * WIM) is examined for consistency and may be split into multiple "true" inodes
+ * that are maximally sized consistent sets of dentries.
*
* Return 0 on success; WIMLIB_ERR_NOMEM or WIMLIB_ERR_INVALID_DENTRY on
* failure. On success, the list of "true" inodes, linked by the i_hlist field,
return ret;
}
-/* Assign inode numbers to a list of inode, and return the next available
+/* Assign inode numbers to a list of inodes and return the next available
* number. */
u64 assign_inode_numbers(struct hlist_head *inode_list)
{
/*
* lookup_table.c
*
- * Lookup table, implemented as a hash table, that maps dentries to file
- * resources.
+ * Lookup table, implemented as a hash table, that maps SHA1 message digests to
+ * data streams.
*/
/*
return -EISDIR;
if (stream_name) {
- struct ads_entry *ads_entry;
+ struct wim_ads_entry *ads_entry;
u16 ads_idx;
ads_entry = inode_get_ads_entry(inode, stream_name,
&ads_idx);
/* Resolve the alternate data streams */
for (u16 i = 0; i < inode->i_num_ads; i++) {
- struct ads_entry *cur_entry = &inode->i_ads_entries[i];
+ struct wim_ads_entry *cur_entry = &inode->i_ads_entries[i];
lte = __lookup_resource(table, cur_entry->hash);
cur_entry->lte = lte;
}
#define LOOKUP_FLAG_ADS_OK 0x00000001
#define LOOKUP_FLAG_DIRECTORY_OK 0x00000002
-/* Not yet used */
-//#define LOOKUP_FLAG_FOLLOW_SYMLINKS 0x00000004
-
-/* A lookup table that is used to translate the hash codes of dentries into the
- * offsets and sizes of uncompressed or compressed file resources. It is
- * implemented as a hash table. */
+/* The lookup table of a WIM file maps SHA1 message digests to streams of data.
+ * Here, the in-memory structure is implemented as a hash table.
+ *
+ * Given a SHA1 message digest, the mapped-to stream is specified by an offset
+ * in the WIM, an uncompressed and compressed size, and resource flags (see
+ * 'struct resource_entry'). But, we associate additional information, such as
+ * a reference count, with each stream, so the actual mapping is from SHA1
+ * message digests to 'struct wim_lookup_table_entry's, each of which contains
+ * an embedded 'struct resource_entry'.
+ *
+ * Note: Everything will break horribly if there is a SHA1 collision.
+ */
struct wim_lookup_table {
struct hlist_head *array;
u64 num_entries;
{
int ret;
struct wim_inode *inode;
- struct ads_entry *ads_entry;
+ struct wim_ads_entry *ads_entry;
size_t res_size;
struct wim_lookup_table_entry *lte;
struct wimfs_context *ctx = wimfs_get_context();
if ((ctx->mount_flags & WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_WINDOWS)
&& (stream_name = path_stream_name(path))) {
/* Make an alternate data stream */
- struct ads_entry *new_entry;
+ struct wim_ads_entry *new_entry;
struct wim_inode *inode;
char *p = (char*)stream_name - 1;
static int wimfs_removexattr(const char *path, const char *name)
{
struct wim_inode *inode;
- struct ads_entry *ads_entry;
+ struct wim_ads_entry *ads_entry;
u16 ads_idx;
struct wimfs_context *ctx = wimfs_get_context();
static int wimfs_setxattr(const char *path, const char *name,
const char *value, size_t size, int flags)
{
- struct ads_entry *existing_ads_entry;
- struct ads_entry *new_ads_entry;
+ struct wim_ads_entry *existing_ads_entry;
+ struct wim_ads_entry *new_ads_entry;
struct wim_lookup_table_entry *existing_lte;
struct wim_lookup_table_entry *lte;
struct wim_inode *inode;
/*
* We provide the use_ino option to the FUSE mount because we are going
- * to assign inode numbers oursides. */
+ * to assign inode numbers ourselves. */
char optstring[256] =
"use_ino"
",subtype=wimfs"
} else {
/* Named data stream. Put the reference to it in the
* alternate data stream entries */
- struct ads_entry *new_ads_entry;
+ struct wim_ads_entry *new_ads_entry;
size_t stream_name_utf8_len;
ret = utf16_to_utf8((const char*)attr_record_name(actx->attr),
/* Get the symlink target from a WIM inode.
*
- * The inode may be either "real" symlink or a junction point.
+ * The inode may be either a "real" symlink (reparse tag
+ * WIM_IO_REPARSE_TAG_SYMLINK), or it may be a junction point (reparse tag
+ * WIM_IO_REPARSE_TAG_MOUNT_POINT).
*/
ssize_t inode_readlink(const struct wim_inode *inode, char *buf, size_t buf_len,
const WIMStruct *w, int read_resource_flags)
struct _ntfs_volume;
#endif
-/* Structure for security data. Each image in the WIM file has its own security
- * data. */
+/* Table of security descriptors for a WIM image. */
struct wim_security_data {
/* The total length of the security data, in bytes. If there are no
- * security descriptors, this field may be either 8 (which is correct)
- * or 0 (which is interpreted as 0). */
+ * security descriptors, this field, when read from the on-disk metadata
+ * resource, may be either 8 (which is correct) or 0 (which is
+ * interpreted as 0). */
u32 total_length;
/* The number of security descriptors in the array @descriptors, below.
- * It is really an unsigned int, but it must fit into an int because the
- * security ID's are signed. (Not like you would ever have more than a
- * few hundred security descriptors anyway.) */
+ * It is really an unsigned int on-disk, but it must fit into an int
+ * because the security ID's are signed. (Not like you would ever have
+ * more than a few hundred security descriptors anyway.) */
int32_t num_entries;
/* Array of sizes of the descriptors in the array @descriptors. */
u32 refcnt;
};
-struct wim_inode_table;
-
-/* Metadata resource for an image. */
+/* Metadata for a WIM image */
struct wim_image_metadata {
- /* Pointer to the root dentry for the image. */
+
+ /* Pointer to the root dentry of the image. */
struct wim_dentry *root_dentry;
- /* Pointer to the security data for the image. */
+ /* Pointer to the security data of the image. */
struct wim_security_data *security_data;
- /* A pointer to the lookup table entry for this image's metadata
- * resource. */
+ /* Pointer to the lookup table entry for this image's metadata resource
+ */
struct wim_lookup_table_entry *metadata_lte;
- /* Linked list of inodes for this image. */
+ /* Linked list of inodes of this image */
struct hlist_head inode_list;
- /* True iff the dentry tree has been modified. If this is the case, the
- * memory for the dentry tree is not freed when switching to a different
- * WIM image. */
+ /* 1 iff the dentry tree has been modified. If this is the case, the
+ * memory for the dentry tree should not be freed when switching to a
+ * different WIM image. */
u8 modified : 1;
- /* True iff this image has been mounted read-write. */
+ /* 1 iff this image has been mounted read-write */
u8 has_been_mounted_rw : 1;
};
/* FILE pointer for the WIM file (if any) currently being written. */
FILE *out_fp;
- /* The name of the WIM file that has been opened. */
+ /* The name of the WIM file (if any) that has been opened. */
char *filename;
/* The lookup table for the WIM file. */